//
//  KATRouter.m
//  KATFramework
//
//  Created by Kantice on 2017/4/25.
//  Copyright © 2017年 KatApp. All rights reserved.
//

#import "KATRouter.h"

#import "KATNavTransition.h"


NSString * const kRouterRootHost=@"router_root_host";
NSString * const kRouterGlobalHost=@"router_global_host";
NSString * const kRouterExecutorHost=@"router_executor_host";
NSString * const kRouterNotificationTypeRemote=@"router_remote_notification";
NSString * const kRouterNotificationTypeLocal=@"router_local_notification";
NSString * const kRouterKeyMessageType=@"router_message_type";
NSString * const kRouterKeyNotificationType=@"router_notification_type";
NSString * const kRouterKeyScheme=@"router_scheme";
NSString * const kRouterKeyUser=@"router_user";
NSString * const kRouterKeyHost=@"router_host";
NSString * const kRouterKeyFromHost=@"router_from_host";
NSString * const kRouterKeyToHost=@"router_to_host";
NSString * const kRouterKeyBackward=@"router_backward";
NSString * const kRouterKeySlideBackgrounds=@"router_slide_backgrounds";
NSString * const kRouterKeyPort=@"router_port";
NSString * const kRouterKeyPath=@"router_path";
NSString * const kRouterKeyAddition=@"router_addition";
NSString * const kRouterKeyFragment=@"router_fragment";
NSString * const kRouterKeyTransitionStyle=@"router_transition_style";
NSString * const kRouterKeyTransitionDuration=@"router_transition_duration";
NSString * const kRouterKeyRoutingWithNewInstance=@"routing_with_new_instance";
NSString * const kRouterKeyRoutingWithMultipleInstance=@"routing_with_multiple_instance";
NSString * const kRouterKeyFromHostSnapshot=@"router_from_host_snapshot";


NSString * const kRouterLogsUploadContentDefaultKey=@"content";
NSString * const kRouterLogsKeyID=@"id";
NSString * const kRouterLogFileSuffix=@"log";
NSString * const kRouterLogsKeyDate=@"date";
NSString * const kRouterLogsKeyLogs=@"logs";
NSString * const kRouterLogsKeyLogDate=@"date";
NSString * const kRouterLogsKeyLogNum=@"num";
NSString * const kRouterLogsKeyLogStatus=@"status";
NSString * const kRouterLogsKeyAppEnterTime=@"enter";
NSString * const kRouterLogsKeyAppLeaveTime=@"leave";
NSString * const kRouterLogsKeyAppDuration=@"duration";
NSString * const kRouterLogsKeyHosts=@"hosts";
NSString * const kRouterLogsKeyHost=@"host";
NSString * const kRouterLogsKeyHostEnterTime=@"enter";
NSString * const kRouterLogsKeyHostLeaveTime=@"leave";
NSString * const kRouterLogsKeyHostDuration=@"duration";
NSString * const kRouterLogsKeyHostURI=@"uri";
NSString * const kRouterLogsKeyEvents=@"events";
NSString * const kRouterLogsKeyEvent=@"event";
NSString * const kRouterLogsKeyEventMessage=@"msg";
NSString * const kRouterLogsKeyEventTime=@"time";
NSString * const kRouterLogsKeyEventTag=@"tag";


NSString * const kRouterQueueRouting=@"kat_router_queue_routing";
NSString * const kRouterQueueLogsSaving=@"kat_router_queue_logs_saving";
NSString * const kRouterQueueLogsUploading=@"kat_router_queue_logs_uploading";
NSString * const kRouterQueueDurationMissions=@"kat_router_queue_duration_missions";


NSString * const kRouterDaysMissions=@"days_missions";
NSString * const kRouterDurationMissions=@"duration_missions";
NSString * const kRouterCountMissions=@"count_missions";

NSString * const kRouterProfile=@"kat_router_profile";
NSString * const kRouterConfigKeyTransitionStyle=@"transition_style";
NSString * const kRouterConfigKeyTransitionStyleKey=@"transition_style_key";
NSString * const kRouterConfigKeyTransitionDuration=@"transition_duration";
NSString * const kRouterConfigKeyTransitionDurationKey=@"transition_duration_key";
NSString * const kRouterConfigKeyRoutingWithNewInstanceKey=@"routing_with_new_instance";
NSString * const kRouterConfigKeyRoutingWithMultipleInstanceKey=@"routing_with_multiple_instance";
NSString * const kRouterConfigKeyLogsDir=@"logs_dir";
NSString * const kRouterConfigKeyKeepLogs=@"keep_logs";
NSString * const kRouterConfigKeyUploadLogs=@"upload_logs";
NSString * const kRouterConfigKeyLogsUploadURL=@"logs_upload_url";
NSString * const kRouterConfigKeyLogsID=@"logs_id";
NSString * const kRouterConfigKeyLogsKeepDays=@"logs_keep_days";
NSString * const kRouterConfigKeyLogsUploadContentKey=@"logs_upload_content_key";
NSString * const kRouterConfigKeyFirstRouteURI=@"first_route_uri";


///多例host标记
NSString *const kRouterMultipleHostMark=@"_$_$_";



#define ROUTER_LOG_STATUS_UNKNOWN 0
#define ROUTER_LOG_STATUS_UPLOADED 1



#define ROUTER_MISSION_TYPE_NONE 0
#define ROUTER_MISSION_TYPE_HISTORY 1
#define ROUTER_MISSION_TYPE_DAY_USING 2
#define ROUTER_MISSION_TYPE_APP_USING 3
#define ROUTER_MISSION_TYPE_HOST_USING 4
#define ROUTER_MISSION_TYPE_EVENT 5
#define ROUTER_MISSION_TYPE_HOST_APP_USING 11
#define ROUTER_MISSION_TYPE_HOST_DAY_USING 12
#define ROUTER_MISSION_TYPE_HOSTS_APP_USING 13
#define ROUTER_MISSION_TYPE_HOSTS_DAY_USING 14
#define ROUTER_MISSION_TYPE_EVENTS_HISTORY 21
#define ROUTER_MISSION_TYPE_EVENTS_APP_USING 22
#define ROUTER_MISSION_TYPE_EVENTS_DAY_USING 23


#define ROUTER_TRANSITION_DURATION_MAX 6.0

#define ROUTER_MISSION_TIMER_INTERVAL 1.0

//路由可用测试间隔
#define ROUTER_ROUTING_TEST_INTERVAL 0.05




///根VC
@interface KATRouterRootVC : UIViewController

@end


///任务
@interface KATRouterMission : NSObject

///名称
@property(nonatomic,copy) NSString *name;

///类型
@property(nonatomic,assign) int type;

///间隔日期
@property(nonatomic,assign) unsigned int days;

///间隔时长
@property(nonatomic,assign) unsigned int duration;

///触发次数
@property(nonatomic,assign) unsigned int count;

///host名
@property(nonatomic,copy) NSString *host;

///事件名
@property(nonatomic,copy) NSString *event;

///host数组
@property(nonatomic,retain) KATArray *hosts;

///事件数组
@property(nonatomic,retain) KATArray *events;

///方法调用者
@property(nonatomic,copy) NSString *observer;

///方法名
@property(nonatomic,copy) NSString *sel;

///需要执行次数
@property(nonatomic,assign) unsigned int times;

///创建的时间
@property(nonatomic,assign) KATDateTime createTime;


///构造方法
+ (instancetype)mission;


@end




@implementation KATRouterMission


//构造方法
+ (instancetype)mission
{
    return [[[self alloc] init] autorelease];
}


//初始化
- (instancetype)init
{
    self=[super init];
    
    self.name=nil;
    self.type=ROUTER_MISSION_TYPE_NONE;
    self.days=0;
    self.duration=0;
    self.count=0;
    self.host=nil;
    self.event=nil;
    self.observer=nil;
    self.sel=nil;
    self.times=0;
    self.createTime=[KATDateUtil now];
    
    return self;
}


//释放内存
- (void)dealloc
{
    [_name release];
    [_host release];
    [_event release];
    [_observer release];
    [_sel release];
    
    [super dealloc];
}


@end



@interface KATRouter()


///App代理
@property(nonatomic,retain) id<UIApplicationDelegate> app;

///App状态
@property(nonatomic,assign) KATRouterAppStatus status;

///窗口
@property(nonatomic,retain) UIWindow *window;

///根VC
@property(nonatomic,retain) KATRouterRootVC *rootVC;

///根VC背景图
@property(nonatomic,retain) UIImageView *rootBg;

///顶层VC
@property(nonatomic,retain) UIViewController *topVC;

///类表
@property(nonatomic,retain) KATHashMap<NSString *> *classMap;

///实例表
@property(nonatomic,retain) KATHashMap<__kindof UIViewController *> *instanceMap;

///容器表
@property(nonatomic,retain) KATHashMap<KATHashMap *> *valueMap;

///回退栈
@property(nonatomic,retain) KATStack<NSString *> *backwardStack;

///消息类型容器
@property(nonatomic,retain) KATHashMap<KATArray<NSString *> *> *messageTypeMap;

///动作执行者容器
@property(nonatomic,retain) KATHashMap *actionObserverMap;

///动作方法容器
@property(nonatomic,retain) KATHashMap *actionSelectorMap;

///host动作执行者容器
@property(nonatomic,retain) KATHashMap *hostActionObserverMap;

///host动作方法容器
@property(nonatomic,retain) KATHashMap *hostActionSelectorMap;

///转场动画风格
@property(nonatomic,assign) KATRouterTransitionStyle transitionStyle;

///转场动画时长
@property(nonatomic,assign) double transitionDuration;

///转场动画风格的key
@property(nonatomic,copy) NSString *transitionStyleKey;

///转场动画时长的key
@property(nonatomic,copy) NSString *transitionDurationKey;

///转场时是否新建实例的key
@property(nonatomic,copy) NSString *routingWithNewInstanceKey;

///转场时是否创建多例的key
@property(nonatomic,copy) NSString *routingWithMultipleInstanceKey;

///导航样式转场动画
@property(nonatomic,retain) KATNavTransition *navTransition;

///标签栏
@property(nonatomic,retain) KATTabBar *tabBar;

///是否默认隐藏标签栏(非关联tab栏的host)
@property(nonatomic,assign) BOOL isAutoHidingTabBar;

///导航栏
@property(nonatomic,retain) KATNavBar *navBar;

///即将显示的host
@property(nonatomic,copy) NSString *showingHost;

///最近一次跳转的URI
@property(nonatomic,copy) NSString *lastURI;

///是否为首次激活(app退出后打开，非进入后台后打开)
@property(nonatomic,assign) BOOL isFirstBecomeActive;

///是否已经加载完成(防止屏幕过早旋转)
@property(nonatomic,assign) BOOL isLoaded;

///是否正在跳转
@property(nonatomic,assign) BOOL isRouting;

///是否正在模态显示
@property(nonatomic,assign) BOOL isPresenting;

///是否在路由中消失(解决WKWebView长按弹窗问题)
@property(nonatomic,assign) BOOL isDismissing;

///是否在回退
@property(nonatomic,assign) BOOL isBacking;

///是否正在等待
@property(nonatomic,assign) BOOL isWaitting;

///是否禁用
@property(nonatomic,assign) BOOL isDisabled;

///是否默认屏幕方向为横屏
@property(nonatomic,assign) BOOL isLandscapeOrientationDefault;

///竖屏方向的host
@property(nonatomic,retain) KATTreeMap *portraitOrientationHosts;

///横屏方向的host
@property(nonatomic,retain) KATTreeMap *landscapeOrientationHosts;

///自由方向的host
@property(nonatomic,retain) KATTreeMap *freeOrientationHosts;

///设置了转场动画的host
@property(nonatomic,retain) KATTreeMap *transitionHosts;

///路由队列
@property(nonatomic,assign) dispatch_queue_t queueRouting;


///App激活后动作
@property(nonatomic,copy) BOOL (^appDidBecomeActiveAction)(void);

///App将要退出活跃动作
@property(nonatomic,copy) BOOL (^appWillResignActiveAction)(void);

///App将要进入前台动作
@property(nonatomic,copy) BOOL (^appWillEnterForegroundAction)(void);

///App进入后台动作
@property(nonatomic,copy) BOOL (^appDidEnterBackgroundAction)(void);

///App将要终止动作
@property(nonatomic,copy) BOOL (^appWillTerminateAction)(void);

///App是否通过URL打开动作
@property(nonatomic,copy) BOOL (^appOpenedWithURLAction)(NSURL *url,KATHashMap *info);

///App收到通知动作
@property(nonatomic,copy) BOOL (^appReceivedNotificationAction)(KATHashMap *info);

///App注册远程通知动作
@property(nonatomic,copy) BOOL (^appRegisteredNotificationAction)(NSData *deviceToken);


///从URI路由跳转时动作
@property(nonatomic,copy) KATHashMap *(^routeWithURIAction)(KATHashMap *uri,id addition);

///所有的路由跳转动作
@property(nonatomic,copy) void (^routeAction)(KATHashMap *values);

///定时器动作(与时长任务共用一个定时器，优先执行改动作，再执行任务)
@property(nonatomic,copy) void (^timerAction)(void);



///历史日志数据
@property(nonatomic,retain) KATTreeMap<KATHashMap *> *historyLogs;

///当日日志数据
@property(nonatomic,retain) KATHashMap *dayLogs;

///当前记录的日志
@property(nonatomic,retain) KATHashMap *appLog;

///当前host的日志
@property(nonatomic,retain) KATHashMap *hostLog;

///日志目录
@property(nonatomic,copy) NSString *logsDir;

///是否记录日志
@property(nonatomic,assign) BOOL shouldKeepLogs;

///日志保存时间
@property(nonatomic,assign) int logsKeepingDays;

///日志上传地址
@property(nonatomic,copy) NSString *logsUploadURL;

///日志用户ID
@property(nonatomic,copy) NSString *logsID;

///日志上传数据包的日志数组属性名
@property(nonatomic,copy) NSString *logsUploadContentKey;

///日志上传数据包的附加属性
@property(nonatomic,retain) KATHashMap *logsUploadExtra;

///日志是否上传
@property(nonatomic,assign) BOOL shouldUploadLogs;

///日志上传后回调动作，返回是否成功
@property(nonatomic,copy) BOOL (^logsDidUploadAction)(NSString *feeback);

///日志保存队列
@property(nonatomic,assign) dispatch_queue_t queueLogsSaving;

///日志上传队列
@property(nonatomic,assign) dispatch_queue_t queueLogsUploading;


///日期相关任务为map
@property(nonatomic,retain) KATHashMap<KATRouterMission *> *daysMissions;

///时长相关任务map
@property(nonatomic,retain) KATHashMap<KATRouterMission *> *durationMissions;

///次数相关任务map
@property(nonatomic,retain) KATHashMap<KATRouterMission *> *countMissions;


///时长相关任务队列
@property(nonatomic,assign) dispatch_queue_t queueDurationMissions;

///时长相关任务定时器
@property(atomic,retain) NSTimer *durationMissionsTimer;

///时长定时器间隔
@property(nonatomic,assign) double timerInterval;


///不自动释放的host
@property(nonatomic,retain) KATTreeMap<NSString *> *alwaysRetainedHosts;

///路由时新建实例的host
@property(nonatomic,retain) KATTreeMap<NSString *> *routingWithNewInstanceHosts;

///路由时创建多个实例的host
@property(nonatomic,retain) KATTreeMap<NSString *> *routingWithMultipleInstanceHosts;

///需要接收屏幕截图的host
@property(nonatomic,retain) KATTreeMap<NSString *> *requiredSnapshotHosts;


///侧滑回退的host
@property(nonatomic,retain) KATTreeMap<NSString *> *slideHosts;

///禁止侧滑回退的host
@property(nonatomic,retain) KATTreeMap<NSString *> *slideDisabledHosts;

///侧滑回退的背景视图表
@property(nonatomic,retain) KATTreeMap<UIView *> *slideBackgroundViews;

///侧滑完成进度点(0~1之间 默认0.4,即超过宽度的40%)
@property(nonatomic,assign) float slideFinishProgress;

///侧滑手势完成条件的滑动尾速(默认为每帧16点)
@property(nonatomic,assign) float slideFinishSpeed;

///侧滑手势起始点X坐标位置(0~1之间,默认0.5,即左半屏)
@property(nonatomic,assign) float slideStartXPoint;

///水平滑动动画效果的host是否自动带侧滑交互(默认是)
@property(nonatomic,assign) BOOL slideAutoSetting;

///侧滑时的背景视图
@property(nonatomic,retain) UIView *slideBackgroundView;

///侧滑时的前景图
@property(nonatomic,retain) UIView *slideForegroundView;

///侧滑的空视图(为了在截图失败时保持与返回栈的一致性)
@property(nonatomic,retain) UIView *slideEmptyView;

///侧滑时的阴影层
@property(nonatomic,retain) UIView *slideShadowView;

///侧滑的距离
@property(nonatomic,assign) double slideDistance;

///侧滑的速度
@property(nonatomic,assign) double slideSpeed;

///是否开始交互
@property(nonatomic,assign) BOOL isSliding;

///是否侧滑禁用(处理过程中)
@property(nonatomic,assign) BOOL slideDisabled;

///侧滑手势表
@property(nonatomic,retain) KATTreeMap *slideGestures;


///配置文件目录
@property(nonatomic,copy) NSString *profile;

///配置
@property(nonatomic,retain) KATHashMap<NSString *> *config;


///提示窗口
@property(nonatomic,retain) KATAlertWindow *alertWindow;

///按钮窗口
@property(nonatomic,retain) KATButtonWindow *buttonWindow;

///选择窗口
@property(nonatomic,retain) KATChoiceWindow *choiceWindow;

///输入窗口
@property(nonatomic,retain) KATInputWindow *inputWindow;

///输入框窗口
@property(nonatomic,retain) KATTextFieldWindow *textFieldWindow;

///等待窗口
@property(nonatomic,retain) KATWaitWindow *waitWindow;

///加载窗口
@property(nonatomic,retain) KATWaitWindow *loadingWindow;

///吐司
@property(nonatomic,retain) KATToast *toast;


///外部跳转保护时间(防止外部跳转回来时横竖屏未及时切换的问题)
@property(nonatomic,assign) double routingProtectionDuration;

///路由最大等待时长
@property(nonatomic,assign) double routingWaitDuration;

///当前是否为横屏
@property(nonatomic,assign) BOOL isCurrentLandscapeOrientation;



@end





@implementation KATRouter


//单例
static KATRouter *_router=nil;

//日志编号位数模
static long long _logNumberMod=10000000LL;



#pragma -mark App代理挂钩

//原始函数指针
static void (*_didBecomeActive)(id,SEL,UIApplication *)=nil;
static void (*_willResignActive)(id,SEL,UIApplication *)=nil;
static void (*_willEnterForeground)(id,SEL,UIApplication *)=nil;
static void (*_didEnterBackground)(id,SEL,UIApplication *)=nil;
static void (*_willTerminate)(id,SEL,UIApplication *)=nil;
static BOOL (*_openWithURL)(id,SEL,UIApplication *,NSURL *,NSDictionary<UIApplicationOpenURLOptionsKey,id> *)=nil;
static void (*_receivedLocalNotification)(id,SEL,UIApplication *,UILocalNotification *)=nil;
static void (*_receivedRemoteNotification)(id,SEL,UIApplication *,NSDictionary *)=nil;
static void (*_receivedRemoteNotificationFetch)(id,SEL,UIApplication *,NSDictionary *,void (^)(UIBackgroundFetchResult))=nil;
static void (*_registeredRemoteNotification)(id,SEL,UIApplication *,NSDictionary *,NSData *)=nil;

static void (*_presentViewController)(id,SEL,UIViewController *,BOOL,void (^)(void))=nil;
static void (*_dismissViewController)(id,SEL,BOOL,void (^)(void))=nil;

static UIInterfaceOrientationMask (*_supportedOrientations)(id,SEL)=nil;



//挂钩方法

//App激活后替换函数
void _appDidBecomeActive(id SELF,SEL _cmd,UIApplication *app)
{
    _router.status=KATRouterAppStatusBecomeActive;
    
    //执行原始方法
    if(_didBecomeActive!=NULL)
    {
        _didBecomeActive(SELF,_cmd,app);
    }
    
    //记录日志
    [_router _loadHostLog];
    
    //是否分发(默认是)
    BOOL dispatch=YES;
    
    //执行路由器动作
    if(_router.appDidBecomeActiveAction)
    {
        dispatch=_router.appDidBecomeActiveAction();
    }
    
    //执行VC回调方法
    if(_router && dispatch)
    {
        if([[KATAppUtil topViewController] conformsToProtocol:@protocol(KATRouterDelegate)])
        {
            UIViewController<KATRouterDelegate> *vc=(UIViewController<KATRouterDelegate> *)[KATAppUtil topViewController];
            
            if([vc respondsToSelector:@selector(appDidBecomeActive)])
            {
                [vc appDidBecomeActive];
            }
        }
    }
    
    //首次路由
    if(_router.isFirstBecomeActive)
    {
        if(_router.config && _router.config[kRouterConfigKeyFirstRouteURI])
        {
            [KATRouter routeWithURI:_router.config[kRouterConfigKeyFirstRouteURI]];
        }
    }
    
    //执行日期任务
    [_router executeDaysMissions];
    
    //启动时长任务定时器
    [_router startDurationMissionTimer];
}


//App将要退出活跃替换函数
void _appWillResignActive(id SELF,SEL _cmd,UIApplication *app)
{
    _router.status=KATRouterAppStatusResignActive;
    
    _router.isFirstBecomeActive=NO;
    
    //执行原始方法
    if(_willResignActive!=NULL)
    {
        _willResignActive(SELF,_cmd,app);
    }
    
    //保存日志
    [_router _saveAppLog];
    
    //是否分发(默认是)
    BOOL dispatch=YES;
    
    //执行路由器动作
    if(_router.appWillResignActiveAction)
    {
        dispatch=_router.appWillResignActiveAction();
    }
    
    //执行VC回调方法
    if(_router && dispatch)
    {
        if([[KATAppUtil topViewController] conformsToProtocol:@protocol(KATRouterDelegate)])
        {
            UIViewController<KATRouterDelegate> *vc=(UIViewController<KATRouterDelegate> *)[KATAppUtil topViewController];
            
            if([vc respondsToSelector:@selector(appWillResignActive)])
            {
                [vc appWillResignActive];
            }
        }
    }
    
    //停止时长任务定时器
    [_router stopDurationMissionTimer];
}


//App将要进入前台替换函数
void _appWillEnterForeground(id SELF,SEL _cmd,UIApplication *app)
{
    _router.status=KATRouterAppStatusEnterForeground;
    
    //执行原始方法
    if(_willEnterForeground!=NULL)
    {
        _willEnterForeground(SELF,_cmd,app);
    }
    
    //是否分发(默认是)
    BOOL dispatch=YES;
    
    //执行路由器动作
    if(_router.appWillEnterForegroundAction)
    {
        dispatch=_router.appWillEnterForegroundAction();
    }
    
    //执行VC回调方法
    if(_router && dispatch)
    {
        if([[KATAppUtil topViewController] conformsToProtocol:@protocol(KATRouterDelegate)])
        {
            UIViewController<KATRouterDelegate> *vc=(UIViewController<KATRouterDelegate> *)[KATAppUtil topViewController];
            
            if([vc respondsToSelector:@selector(appWillEnterForeground)])
            {
                [vc appWillEnterForeground];
            }
        }
    }
}


//App进入后台替换函数
void _appDidEnterBackground(id SELF,SEL _cmd,UIApplication *app)
{
    _router.status=KATRouterAppStatusEnterBackground;
    
    //执行原始方法
    if(_didEnterBackground!=NULL)
    {
        _didEnterBackground(SELF,_cmd,app);
    }
    
    //是否分发(默认是)
    BOOL dispatch=YES;
    
    //执行路由器动作
    if(_router.appDidEnterBackgroundAction)
    {
        dispatch=_router.appDidEnterBackgroundAction();
    }
    
    //执行VC回调方法
    if(_router && dispatch)
    {
        if([[KATAppUtil topViewController] conformsToProtocol:@protocol(KATRouterDelegate)])
        {
            UIViewController<KATRouterDelegate> *vc=(UIViewController<KATRouterDelegate> *)[KATAppUtil topViewController];
            
            if([vc respondsToSelector:@selector(appDidEnterBackground)])
            {
                [vc appDidEnterBackground];
            }
        }
    }
}


//App将要终止替换函数
void _appWillTerminate(id SELF,SEL _cmd,UIApplication *app)
{
    _router.status=KATRouterAppStatusTerminate;
    
    //执行原始方法
    if(_willTerminate!=NULL)
    {
        _willTerminate(SELF,_cmd,app);
    }
    
    //是否分发(默认是)
    BOOL dispatch=YES;
    
    //执行路由器动作
    if(_router.appWillTerminateAction)
    {
        dispatch=_router.appWillTerminateAction();
    }
    
    //执行VC回调方法
    if(_router && dispatch)
    {
        if([[KATAppUtil topViewController] conformsToProtocol:@protocol(KATRouterDelegate)])
        {
            UIViewController<KATRouterDelegate> *vc=(UIViewController<KATRouterDelegate> *)[KATAppUtil topViewController];
            
            if([vc respondsToSelector:@selector(appWillTerminate)])
            {
                [vc appWillTerminate];
            }
        }
    }
}


//App通过URL打开替换函数
BOOL _appOpenedWithURL(id SELF,SEL _cmd,UIApplication *app,NSURL *url,NSDictionary<UIApplicationOpenURLOptionsKey,id> *options)
{
    _router.status=KATRouterAppStatusOpenedWithURL;
    
    //执行原始方法
    BOOL result=NO;
    
    if(_openWithURL)
    {
        result=_openWithURL(SELF,_cmd,app,url,options);
    }
    
    [_router adjustOritation];
    
    //开启保护时间
    _router.routingProtectionDuration=1.6;
    
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.6 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^
    {
        _router.routingProtectionDuration=0.0;
    });
    
    KATHashMap *info=[KATHashMap hashMapWithDictionary:options];
    
    //执行路由器动作
    if(_router.appOpenedWithURLAction)
    {
        result=_router.appOpenedWithURLAction(url, info);
    }
    
    //执行VC回调方法
    if(_router)
    {
        if([[KATAppUtil topViewController] conformsToProtocol:@protocol(KATRouterDelegate)])
        {
            UIViewController<KATRouterDelegate> *vc=(UIViewController<KATRouterDelegate> *)[KATAppUtil topViewController];
            
            if([vc respondsToSelector:@selector(appOpenedWithURL:andInfo:)])
            {
                result=[vc appOpenedWithURL:url andInfo:info];
            }
        }
    }
    
    return result;
}


//App收到本地通知替换函数
void _appReceivedLocalNotification(id SELF,SEL _cmd,UIApplication *app,UILocalNotification *notification)
{
    //执行原始方法
    if(_receivedLocalNotification!=NULL)
    {
        _receivedLocalNotification(SELF,_cmd,app,notification);
    }
    
    //信息
    KATHashMap *info=[KATHashMap hashMapWithDictionary:notification.userInfo];
    info[kRouterKeyNotificationType]=kRouterNotificationTypeLocal;
    
    //是否分发(默认是)
    BOOL dispatch=YES;
    
    //执行路由器动作
    if(_router.appReceivedNotificationAction)
    {
        dispatch=_router.appReceivedNotificationAction(info);
    }
    
    //执行VC回调方法
    if(_router && dispatch)
    {
        if([[KATAppUtil topViewController] conformsToProtocol:@protocol(KATRouterDelegate)])
        {
            UIViewController<KATRouterDelegate> *vc=(UIViewController<KATRouterDelegate> *)[KATAppUtil topViewController];
            
            if([vc respondsToSelector:@selector(appReceivedNotification:)])
            {
                [vc appReceivedNotification:info];
            }
        }
    }
}


//App收到远程通知替换函数
void _appReceivedRemoteNotification(id SELF,SEL _cmd,UIApplication *app,NSDictionary *dict)
{
    //执行原始方法
    if(_receivedRemoteNotification!=NULL)
    {
        _receivedRemoteNotification(SELF,_cmd,app,dict);
    }
    
    //信息
    KATHashMap *info=[KATHashMap hashMapWithDictionary:dict];
    info[kRouterKeyNotificationType]=kRouterNotificationTypeRemote;
    
    //是否分发(默认是)
    BOOL dispatch=YES;
    
    //执行路由器动作
    if(_router.appReceivedNotificationAction)
    {
        dispatch=_router.appReceivedNotificationAction(info);
    }
    
    //执行VC回调方法
    if(_router && dispatch)
    {
        if([[KATAppUtil topViewController] conformsToProtocol:@protocol(KATRouterDelegate)])
        {
            UIViewController<KATRouterDelegate> *vc=(UIViewController<KATRouterDelegate> *)[KATAppUtil topViewController];
            
            if([vc respondsToSelector:@selector(appReceivedNotification:)])
            {
                [vc appReceivedNotification:info];
            }
        }
    }
}


//App收到远程通知替换函数
void _appReceivedRemoteNotificationFetch(id SELF,SEL _cmd,UIApplication *app,NSDictionary *dict,void (^handle)(UIBackgroundFetchResult))
{
    //执行原始方法
    if(_receivedRemoteNotificationFetch!=NULL)
    {
//        if(handle)//注释掉是为了避免重复调用导致的潜在的问题，特别是性能较差的设备，容易奔溃
//        {
//            handle(UIBackgroundFetchResultNewData);
//        }
        
        _receivedRemoteNotificationFetch(SELF,_cmd,app,dict,handle);
    }
    
    //信息
    KATHashMap *info=[KATHashMap hashMapWithDictionary:dict];
    info[kRouterKeyNotificationType]=kRouterNotificationTypeRemote;
    
    //是否分发(默认是)
    BOOL dispatch=YES;
    
    //执行路由器动作
    if(_router.appReceivedNotificationAction)
    {
        dispatch=_router.appReceivedNotificationAction(info);
    }
    
    //执行VC回调方法
    if(_router && dispatch)
    {
        if([[KATAppUtil topViewController] conformsToProtocol:@protocol(KATRouterDelegate)])
        {
            UIViewController<KATRouterDelegate> *vc=(UIViewController<KATRouterDelegate> *)[KATAppUtil topViewController];
            
            if([vc respondsToSelector:@selector(appReceivedNotification:)])
            {
                [vc appReceivedNotification:info];
            }
        }
    }
}


//App注册远程通知替换函数
void _appRegisteredRemoteNotification(id SELF,SEL _cmd,UIApplication *app,NSDictionary *dict,NSData *data)
{
    //执行原始方法
    if(_registeredRemoteNotification!=NULL)
    {
        _registeredRemoteNotification(SELF,_cmd,app,dict,data);
    }
    
    //是否分发(默认是)
    BOOL dispatch=YES;
    
    //执行路由器动作
    if(_router.appRegisteredNotificationAction)
    {
        dispatch=_router.appRegisteredNotificationAction(data);
    }
    
    //执行VC回调方法
    if(_router && dispatch)
    {
        if([[KATAppUtil topViewController] conformsToProtocol:@protocol(KATRouterDelegate)])
        {
            UIViewController<KATRouterDelegate> *vc=(UIViewController<KATRouterDelegate> *)[KATAppUtil topViewController];
            
            if([vc respondsToSelector:@selector(appRegisteredRemoteNotificationWithDeviceToken:)])
            {
                [vc appRegisteredRemoteNotificationWithDeviceToken:data];
            }
        }
    }
}


//app支持的屏幕方向替换函数
UIInterfaceOrientationMask _appSupportedOrientations(id SELF,SEL _cmd,UIApplication *app,UIWindow *window)
{
    if(_router.isLoaded)
    {
        return UIInterfaceOrientationMaskAll;
    }
    else
    {
        return UIInterfaceOrientationMaskPortrait;
    }
}


//VC模态展示替换函数
void _VCPresentVC(id SELF,SEL _cmd,UIViewController *vc,BOOL animated,void (^action)(void))
{
//    NSString *host=objc_getAssociatedObject(vc, kRouterKeyHost);
    
    KATRouter *router=[KATRouter sharedRouter];
    
    //完成行为
    void (^completion)(void)=^(void)
    {
        if(action)
        {
            action();
        }
        
        router.isPresenting=NO;
    };

    //执行原始方法
    if(_presentViewController!=NULL)
    {
        router.isPresenting=YES;
        router.isRouting=NO;
        
        _presentViewController(SELF,_cmd,vc,animated,completion);
    }
}


//VC模态消失替换函数
void _VCDismiss(id SELF,SEL _cmd,BOOL animated,void (^action)(void))
{
    KATRouter *router=[KATRouter sharedRouter];
    
    if(objc_getAssociatedObject(SELF, kRouterKeyHost))//注册过的VC
    {
        if(!router.isDismissing)//非路由器调用dismiss
        {
            if(SELF==[KATAppUtil topViewController])
            {
                return;
            }
        }
    }
    
    //完成行为
    void (^completion)(void)=^(void)
    {
        if(action)
        {
            action();
        }
        
        //调整屏幕方向
        [router adjustOritation];
    };
    
    //执行原始方法
    if(_dismissViewController!=NULL)
    {
        _dismissViewController(SELF,_cmd,animated,completion);
    }
}


//VC支持的屏幕方向(只有返回UIInterfaceOrientationMaskAll的时候，强制翻转屏幕才会生效)
UIInterfaceOrientationMask _VCSupportedOrientations(id SELF,SEL _cmd)
{
    KATRouter *router=[KATRouter sharedRouter];
    
    if(router.status!=KATRouterAppStatusEnterForeground && router.status!=KATRouterAppStatusEnterBackground)
    {
        return UIInterfaceOrientationMaskAll;
    }
    
    //执行原方法
    if(_supportedOrientations!=NULL)
    {
        return _supportedOrientations(SELF,_cmd);
    }
    
    NSString *host=objc_getAssociatedObject(SELF, kRouterKeyHost);
    
    if(host)//注册过
    {
        //多例处理
        NSRange range=[host rangeOfString:kRouterMultipleHostMark];
        
        if(range.length>0)
        {
            host=[host substringToIndex:range.location];//原始host
        }
        
        //先判断是否为自由方向
        if([router.freeOrientationHosts getValueWithKey:host])
        {
            return UIInterfaceOrientationMaskAll;
        }
        
        if(router.isLandscapeOrientationDefault)//默认横屏
        {
            if([router.portraitOrientationHosts getValueWithKey:host])
            {
                return (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown);
            }
            else
            {
                return (UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight);
            }
        }
        else//默认竖屏
        {
            if([router.landscapeOrientationHosts getValueWithKey:host])
            {
                return (UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight);
            }
            else
            {
                return (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown);
            }
        }
    }
    
    return UIInterfaceOrientationMaskAll;
}


//挂钩VC支持屏幕方向方法
+ (void)hookSupportedOrientationsWithVC:(UIViewController *)vc
{
    if([vc respondsToSelector:@selector(supportedInterfaceOrientations)])
    {
        //替换
        class_replaceMethod([UIViewController class], @selector(supportedInterfaceOrientations), (IMP)_VCSupportedOrientations, NULL);
    }
    else
    {
        //添加
        class_addMethod([UIViewController class], @selector(supportedInterfaceOrientations), (IMP)_VCSupportedOrientations, NULL);
    }
}


//挂钩App代理方法
+ (void)hookAppDelegate
{
    static dispatch_once_t onceToken;
    
    dispatch_once(&onceToken, ^
    {
        if(_router.app)
        {
            //app将要激活
            if([_router.app respondsToSelector:@selector(applicationDidBecomeActive:)])
            {
                _didBecomeActive=(void(*)(id,SEL,UIApplication*))class_getMethodImplementation([_router.app class], @selector(applicationDidBecomeActive:));
                
                //替换
                class_replaceMethod([_router.app class],@selector(applicationDidBecomeActive:),(IMP)_appDidBecomeActive,NULL);
            }
            else
            {
                //添加
                class_addMethod([_router.app class],@selector(applicationDidBecomeActive:),(IMP)_appDidBecomeActive,NULL);
                
                //注册通知
                [[NSNotificationCenter defaultCenter] addObserver:_router.app selector:@selector(applicationDidBecomeActive:) name:UIApplicationDidBecomeActiveNotification object:nil];
            }
            
            //app退出活跃
            if([_router.app respondsToSelector:@selector(applicationWillResignActive:)])
            {
                _willResignActive=(void(*)(id,SEL,UIApplication*))class_getMethodImplementation([_router.app class], @selector(applicationWillResignActive:));
                
                //替换
                class_replaceMethod([_router.app class],@selector(applicationWillResignActive:),(IMP)_appWillResignActive,NULL);
            }
            else
            {
                //添加
                class_addMethod([_router.app class],@selector(applicationWillResignActive:),(IMP)_appWillResignActive,NULL);
                
                //注册通知
                [[NSNotificationCenter defaultCenter] addObserver:_router.app selector:@selector(applicationWillResignActive:) name:UIApplicationWillResignActiveNotification object:nil];
            }
            
            //app将要进入前台
            if([_router.app respondsToSelector:@selector(applicationWillEnterForeground:)])
            {
                _willEnterForeground=(void(*)(id,SEL,UIApplication*))class_getMethodImplementation([_router.app class], @selector(applicationWillEnterForeground:));
                
                //替换
                class_replaceMethod([_router.app class],@selector(applicationWillEnterForeground:),(IMP)_appWillEnterForeground,NULL);
            }
            else
            {
                //添加
                class_addMethod([_router.app class],@selector(applicationWillEnterForeground:),(IMP)_appWillEnterForeground,NULL);
                
                //注册通知
                [[NSNotificationCenter defaultCenter] addObserver:_router.app selector:@selector(applicationWillEnterForeground:) name:UIApplicationWillEnterForegroundNotification object:nil];
            }
                          
            //app进入后台
            if([_router.app respondsToSelector:@selector(applicationDidEnterBackground:)])
            {
                _didEnterBackground=(void(*)(id,SEL,UIApplication*))class_getMethodImplementation([_router.app class], @selector(applicationDidEnterBackground:));
                
                //替换
                class_replaceMethod([_router.app class],@selector(applicationDidEnterBackground:),(IMP)_appDidEnterBackground,NULL);
            }
            else
            {
                //添加
                class_addMethod([_router.app class],@selector(applicationDidEnterBackground:),(IMP)_appDidEnterBackground,NULL);
            
                //注册通知
                [[NSNotificationCenter defaultCenter] addObserver:_router.app selector:@selector(applicationDidEnterBackground:) name:UIApplicationDidEnterBackgroundNotification object:nil];
            }
            
            //app将要终止
            if([_router.app respondsToSelector:@selector(applicationWillTerminate:)])
            {
                _willTerminate=(void(*)(id,SEL,UIApplication*))class_getMethodImplementation([_router.app class], @selector(applicationWillTerminate:));
                
                //替换
                class_replaceMethod([_router.app class],@selector(applicationWillTerminate:),(IMP)_appWillTerminate,NULL);
            }
            else
            {
                //添加
                class_addMethod([_router.app class],@selector(applicationWillTerminate:),(IMP)_appWillTerminate,NULL);
                
                //注册通知
                [[NSNotificationCenter defaultCenter] addObserver:_router.app selector:@selector(applicationWillTerminate:) name:UIApplicationWillTerminateNotification object:nil];
            }
            
            //app是否通过URL打开
            if([_router.app respondsToSelector:@selector(application:openURL:options:)])
            {
                _openWithURL=(BOOL(*)(id,SEL,UIApplication*,NSURL *,NSDictionary<UIApplicationOpenURLOptionsKey,id> *))class_getMethodImplementation([_router.app class], @selector(application:openURL:options:));
            
                //替换
                class_replaceMethod([_router.app class],@selector(application:openURL:options:),(IMP)_appOpenedWithURL,NULL);
            }
            else
            {
                //添加
                class_addMethod([_router.app class],@selector(application:openURL:options:),(IMP)_appOpenedWithURL,NULL);
                
                //注册通知
                //没有找到对应的通知
            }
            
            //app收到本地通知
            if([_router.app respondsToSelector:@selector(application:didReceiveLocalNotification:)])
            {
                _receivedLocalNotification=(void(*)(id,SEL,UIApplication*,UILocalNotification*))class_getMethodImplementation([_router.app class], @selector(application:didReceiveLocalNotification:));
                
                //替换
                class_replaceMethod([_router.app class],@selector(application:didReceiveLocalNotification:),(IMP)_appReceivedLocalNotification,NULL);
            }
            else
            {
                //添加
                class_addMethod([_router.app class],@selector(application:didReceiveLocalNotification:),(IMP)_appReceivedLocalNotification,NULL);
                
                //注册通知
                //没有找到对应的通知
            }
            
            //app收到远程通知
            if([_router.app respondsToSelector:@selector(application:didReceiveRemoteNotification:)])
            {
                _receivedRemoteNotification=(void(*)(id,SEL,UIApplication*,NSDictionary*))class_getMethodImplementation([_router.app class], @selector(application:didReceiveRemoteNotification:));
                
                //替换
                class_replaceMethod([_router.app class],@selector(application:didReceiveRemoteNotification:),(IMP)_appReceivedRemoteNotification,NULL);
            }
            else
            {
                //添加
                class_addMethod([_router.app class],@selector(application:didReceiveRemoteNotification:),(IMP)_appReceivedRemoteNotification,NULL);
                
                //注册通知
                //没有找到对应的通知
            }
            
            //app收到远程通知
            if([_router.app respondsToSelector:@selector(application:didReceiveRemoteNotification:fetchCompletionHandler:)])
            {
                _receivedRemoteNotificationFetch=(void(*)(id,SEL,UIApplication*,NSDictionary*,void (^)(UIBackgroundFetchResult)))class_getMethodImplementation([_router.app class], @selector(application:didReceiveRemoteNotification:fetchCompletionHandler:));
                
                //替换
                class_replaceMethod([_router.app class],@selector(application:didReceiveRemoteNotification:fetchCompletionHandler:),(IMP)_appReceivedRemoteNotificationFetch,NULL);
            }
            else
            {
                //添加
                class_addMethod([_router.app class],@selector(application:didReceiveRemoteNotification:fetchCompletionHandler:),(IMP)_appReceivedRemoteNotificationFetch,NULL);
                
                //注册通知
                //没有找到对应的通知
            }
            
            //app注册远程通知
            if([_router.app respondsToSelector:@selector(application:didRegisterForRemoteNotificationsWithDeviceToken:)])
            {
                _registeredRemoteNotification=(void(*)(id,SEL,UIApplication*,NSDictionary*,NSData *))class_getMethodImplementation([_router.app class], @selector(application:didRegisterForRemoteNotificationsWithDeviceToken:));
                
                //替换
                class_replaceMethod([_router.app class],@selector(application:didRegisterForRemoteNotificationsWithDeviceToken:),(IMP)_appRegisteredRemoteNotification,NULL);
            }
            else
            {
                //添加
                class_addMethod([_router.app class],@selector(application:didRegisterForRemoteNotificationsWithDeviceToken:),(IMP)_appRegisteredRemoteNotification,NULL);
                
                //注册通知
                //没有找到对应的通知
            }
            
            //app支持的屏幕方向
//            if([_router.app respondsToSelector:@selector(application:supportedInterfaceOrientationsForWindow:)])
//            {
//                //替换
//                class_replaceMethod([_router.app class],@selector(application:supportedInterfaceOrientationsForWindow:),(IMP)_appSupportedOrientations,NULL);
//            }
//            else
//            {
//                //添加
//                class_addMethod([_router.app class],@selector(application:didReceiveRemoteNotification:),(IMP)_appSupportedOrientations,NULL);
//            }
            
            //VC跳转VC
            _presentViewController=(void(*)(id,SEL,UIViewController *,BOOL,void (^)(void)))class_getMethodImplementation([UIViewController class], @selector(presentViewController:animated:completion:));
            class_replaceMethod([UIViewController class], @selector(presentViewController:animated:completion:), (IMP)_VCPresentVC, NULL);
            
            //VC消失
            _dismissViewController=(void(*)(id,SEL,BOOL,void (^)(void)))class_getMethodImplementation([UIViewController class], @selector(dismissViewControllerAnimated:completion:));
            class_replaceMethod([UIViewController class], @selector(dismissViewControllerAnimated:completion:), (IMP)_VCDismiss, NULL);
        }
    });
}



#pragma -mark App代理回调动作


//设置App激活后动作
+ (void)setAppDidBecomeActiveAction:(BOOL (^)(void))action
{
    KATRouter *router=[self sharedRouter];
    
    router.appDidBecomeActiveAction=action;
}


//设置App将要退出活跃动作
+ (void)setAppWillResignActiveAction:(BOOL (^)(void))action
{
    KATRouter *router=[self sharedRouter];
    
    router.appWillResignActiveAction=action;
}


//设置App将要进入前台动作
+ (void)setAppWillEnterForegroundAction:(BOOL (^)(void))action
{
    KATRouter *router=[self sharedRouter];
    
    router.appWillEnterForegroundAction=action;
}


//设置App进入后台动作
+ (void)setAppDidEnterBackgroundAction:(BOOL (^)(void))action
{
    KATRouter *router=[self sharedRouter];
    
    router.appDidEnterBackgroundAction=action;
}


//设置App将要终止动作
+ (void)setAppWillTerminateAction:(BOOL (^)(void))action
{
    KATRouter *router=[self sharedRouter];
    
    router.appWillTerminateAction=action;
}


//设置App是否通过URL中打开动作
+ (void)setAppOpenedWithURLAction:(BOOL (^)(NSURL *url,KATHashMap *map))action
{
    KATRouter *router=[self sharedRouter];
    
    router.appOpenedWithURLAction=action;
}


//设置APP收到本地通知
+ (void)setAppReceivedNotificationAction:(BOOL (^)(KATHashMap *))action
{
    KATRouter *router=[self sharedRouter];
    
    router.appReceivedNotificationAction=action;
}


//设置App注册远程通知动作
+ (void)setAppRegisterNotificationAction:(BOOL (^)(NSData *deviceToken))action
{
    KATRouter *router=[self sharedRouter];
    
    router.appRegisteredNotificationAction=action;
}


//设置路由跳转时的动作(只针对routeWithURI:方法)
+ (void)setRouteWithURIAction:(KATHashMap *(^)(KATHashMap *uri,id addition))action
{
    KATRouter *router=[self sharedRouter];
    
    router.routeWithURIAction=action;
}


///设置路由跳转时的动作(所有跳转方法)
+ (void)setRouteAction:(void (^)(KATHashMap *values))action
{
    KATRouter *router=[self sharedRouter];
    
    router.routeAction=action;
}


//设置定时器动作(与时长任务共用一个定时器，优先执行改动作，再执行任务)
+ (void)setTimerAction:(void (^)(void))action
{
    KATRouter *router=[self sharedRouter];
    
    router.timerAction=action;
    
    if(router.timerAction)
    {
        //启动定时器
        [router startDurationMissionTimer];
    }
}


#pragma -mark 内部方法


//获取单例
+ (instancetype)sharedRouter
{
    static dispatch_once_t onceToken;
    
    dispatch_once(&onceToken, ^
    {
        //初始化
        _router=[[self alloc] init];
        
        _router.app=[UIApplication sharedApplication].delegate;
        _router.topVC=nil;
        _router.classMap=[KATHashMap hashMap];
        _router.instanceMap=[KATHashMap hashMap];
        _router.backwardStack=[KATStack stackWithCapacity:1024];
        _router.valueMap=[KATHashMap hashMap];
        _router.messageTypeMap=[KATHashMap hashMap];
        _router.valueMap[kRouterGlobalHost]=[KATHashMap hashMap];
        _router.actionObserverMap=[KATHashMap hashMap];
        _router.actionSelectorMap=[KATHashMap hashMap];
        _router.hostActionObserverMap=[KATHashMap hashMap];
        _router.hostActionSelectorMap=[KATHashMap hashMap];
        _router.transitionStyle=KATRouterTransitionStyleFade;
        _router.transitionDuration=0.3;
        _router.transitionStyleKey=kRouterKeyTransitionStyle;
        _router.transitionDurationKey=kRouterKeyTransitionDuration;
        _router.routingWithNewInstanceKey=kRouterKeyRoutingWithNewInstance;
        _router.routingWithMultipleInstanceKey=kRouterKeyRoutingWithMultipleInstance;
        _router.rootVC=nil;
        _router.tabBar=nil;
        _router.isAutoHidingTabBar=NO;
        _router.isLandscapeOrientationDefault=NO;
        _router.portraitOrientationHosts=[KATTreeMap treeMap];
        _router.landscapeOrientationHosts=[KATTreeMap treeMap];
        _router.freeOrientationHosts=[KATTreeMap treeMap];
        _router.transitionHosts=[KATTreeMap treeMap];
        _router.lastURI=@"";
        _router.queueRouting=dispatch_queue_create([kRouterQueueRouting UTF8String], DISPATCH_QUEUE_SERIAL);
        _router.alwaysRetainedHosts=[KATTreeMap treeMap];
        _router.routingWithNewInstanceHosts=[KATTreeMap treeMap];
        _router.routingWithMultipleInstanceHosts=[KATTreeMap treeMap];
        _router.requiredSnapshotHosts=[KATTreeMap treeMap];
        _router.isRouting=NO;
        _router.isPresenting=NO;
        _router.isDismissing=NO;
        _router.isBacking=NO;
        _router.isWaitting=NO;
        _router.isDisabled=NO;
        _router.routingProtectionDuration=0.0;
        _router.routingWaitDuration=ROUTER_TRANSITION_DURATION_MAX;
        _router.showingHost=kRouterRootHost;
        _router.isCurrentLandscapeOrientation=NO;
        
        //侧滑回退
        _router.slideHosts=[KATTreeMap treeMap];
        _router.slideDisabledHosts=[KATTreeMap treeMap];
        _router.slideBackgroundViews=[KATTreeMap treeMap];
        _router.slideFinishProgress=0.4;
        _router.slideStartXPoint=0.5;
        _router.slideFinishSpeed=16.0;
        _router.slideAutoSetting=YES;
        _router.slideBackgroundView=nil;
        _router.slideForegroundView=nil;
        _router.slideEmptyView=[[[UIView alloc] init] autorelease];
        _router.slideShadowView=nil;
        _router.slideDistance=0.0;
        _router.slideSpeed=0.0;
        _router.isSliding=NO;
        _router.slideDisabled=NO;
        _router.slideGestures=[KATTreeMap treeMap];
        
        //app代理事件
        _router.appDidBecomeActiveAction=nil;
        _router.appWillResignActiveAction=nil;
        _router.appDidEnterBackgroundAction=nil;
        _router.appWillTerminateAction=nil;
        _router.appReceivedNotificationAction=nil;
        
        _router.routeWithURIAction=nil;
        _router.routeAction=nil;
        _router.timerAction=nil;
        
        //日志
        _router.shouldKeepLogs=YES;
        _router.shouldUploadLogs=NO;
        _router.logsUploadURL=nil;
        _router.logsID=nil;
        _router.logsUploadContentKey=kRouterLogsUploadContentDefaultKey;
        _router.logsUploadExtra=nil;
        _router.logsDidUploadAction=nil;
        _router.queueLogsSaving=dispatch_queue_create([kRouterQueueLogsSaving UTF8String], DISPATCH_QUEUE_SERIAL);
        _router.queueLogsUploading=dispatch_queue_create([kRouterQueueLogsUploading UTF8String], DISPATCH_QUEUE_SERIAL);
        _router.queueDurationMissions=dispatch_queue_create([kRouterQueueDurationMissions UTF8String], DISPATCH_QUEUE_SERIAL);
        
        //加载日志文件和配置文件
        [_router loadLogs];
        
        //日志行为
        _router.daysMissions=nil;
        _router.durationMissions=nil;
        _router.countMissions=nil;
        _router.timerInterval=ROUTER_MISSION_TIMER_INTERVAL;
        
        //app进入前台行为
        _router.appWillEnterForegroundAction=^
        {
            //徽标清零
            [KATAppUtil setBadgeNumber:0];
            
            return YES;
        };
          
        //app从URL打开行为
        _router.appOpenedWithURLAction=^BOOL(NSURL *url, KATHashMap *info)
        {
            //防止app没启动时跳转过快问题
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^
            {
                //URI跳转
                [KATRouter routeWithURI:[url absoluteString] addition:info];
            });
        
            return YES;
        };
        
        //注册屏幕旋转事件通知
        [[NSNotificationCenter defaultCenter] addObserver:_router selector:@selector(deviceOrientationDidChange) name:UIDeviceOrientationDidChangeNotification object:nil];//方向改变
        
        //App代理方法挂钩
        [self hookAppDelegate];
        
        _router.isFirstBecomeActive=YES;
        _router.isLoaded=NO;
        
        
        //根VC
        _router.rootVC=[[[KATRouterRootVC alloc] init] autorelease];
//        _router.rootVC.view.contentMode=UIViewContentModeScaleAspectFill;
//        _router.rootVC.view.layer.contents=[KATAppUtil launchImage].CGImage;
        
        //根VC背景图
        _router.rootBg=[[[UIImageView alloc] init] autorelease];
        _router.rootBg.bounds=_router.rootVC.view.bounds;
        _router.rootBg.center=POINT(_router.rootVC.view.bounds.size.width/2.0, _router.rootVC.view.bounds.size.height/2.0);
        _router.rootBg.contentMode=UIViewContentModeScaleAspectFill;
        _router.rootBg.image=[KATAppUtil launchImage];
        
        if(!_router.rootBg.image)
        {
            if(_router.rootVC.view.bounds.size.width<_router.rootVC.view.bounds.size.height)//竖屏没有启动图
            {
                _router.rootBg.image=[KATAppUtil landscapeLaunchImage];//使用横屏启动图
                
                if(_router.rootBg.image)
                {
                    _router.rootBg.bounds=RECT(0, 0, _router.rootVC.view.bounds.size.height, _router.rootVC.view.bounds.size.width);
                    _router.rootBg.center=POINT(_router.rootVC.view.bounds.size.height/2.0, _router.rootVC.view.bounds.size.width/2.0);
                    
//                    _router.rootBg.layer.transform=CATransform3DRotate(CATransform3DIdentity, M_PI*0.5, 0.0, 0.0, 1.0);
                }
            }
            else//横屏没有启动图
            {
                _router.rootBg.image=[KATAppUtil portraitLaunchImage];//使用竖屏启动图
                
                if(_router.rootBg.image)
                {
                    _router.rootBg.bounds=RECT(0, 0, _router.rootVC.view.bounds.size.height, _router.rootVC.view.bounds.size.width);
                    _router.rootBg.center=POINT(_router.rootVC.view.bounds.size.height/2.0, _router.rootVC.view.bounds.size.width/2.0);
                    
//                    _router.rootBg.layer.transform=CATransform3DRotate(CATransform3DIdentity, -M_PI*0.5, 0.0, 0.0, 1.0);
                }
            }
        }
        
        
        [_router.rootVC.view addSubview:_router.rootBg];
        
        
        //注册
        _router.classMap[kRouterRootHost]=NSStringFromClass([_router.rootVC class]);
        
        //关联host
        objc_setAssociatedObject(_router.rootVC, kRouterKeyHost, kRouterRootHost, OBJC_ASSOCIATION_COPY_NONATOMIC);
        _router.instanceMap[kRouterRootHost]=_router.rootVC;
        _router.valueMap[kRouterRootHost]=[KATHashMap hashMap];
        
        //设置根视图控制器
        _router.window=[KATAppUtil keyWindow];
        
        if(!_router.window)//不存在主窗口则创建
        {
            _router.window=[[[UIWindow alloc] initWithFrame:RECT(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT)] autorelease];
        }
        
        [_router.window setRootViewController:_router.rootVC];
                
        
        //设置导航栏
        KATNavBar *nav=[KATNavBar navBar];
        
        nav.backButton.onClickAction=^
        {
            [KATRouter backwardWithQuery:[NSString stringWithFormat:@"%@=%lu",_router.transitionStyleKey,(unsigned long)KATRouterTransitionStyleNavHorizontal]];
        };
        
        _router.navBar=nav;
        
        //弹窗
        _router.alertWindow=nil;
        _router.buttonWindow=nil;
        _router.choiceWindow=nil;
        _router.inputWindow=nil;
        _router.textFieldWindow=nil;
        _router.waitWindow=nil;
        _router.loadingWindow=nil;
        _router.toast=nil;
        
        
        [_router.window makeKeyAndVisible];
        
        [_router.window addSubview:_router.navBar];
        
    });
    
    return _router;
}


//重写alloc
+ (instancetype)alloc
{
    if(_router)
    {
        return nil;
    }
    else
    {
        return [super alloc];
    }
}


//加载配置文件
- (void)loadConfig
{
    if(!_config)
    {
        self.profile=[NSString stringWithFormat:@"%@/%@",DOCUMENTS_PATH,kRouterProfile];
        
        if(![KATFileUtil existsFile:_profile])//不存在该目录(首次运行)
        {
            self.config=[KATHashMap hashMap];
        }
        else//存在配置文件
        {
            self.config=[KATHashMap hashMapWithFile:_profile];
        }
        
        
        //读取配置
        
        if(_config[kRouterConfigKeyTransitionStyle])
        {
            self.transitionStyle=[_config[kRouterConfigKeyTransitionStyle] intValue];
        }
        
        if(_config[kRouterConfigKeyTransitionStyleKey])
        {
            self.transitionStyleKey=_config[kRouterConfigKeyTransitionStyleKey];
            
            //导航栏返回按钮
            if(_navBar)
            {
                dispatch_async(dispatch_get_main_queue(), ^
                {
                    _navBar.backButton.onClickAction=^
                    {
                        [KATRouter backwardWithQuery:[NSString stringWithFormat:@"%@=%lu",_router.transitionStyleKey,(unsigned long)KATRouterTransitionStyleNavHorizontal]];
                    };
                });
            }
        }
        
        if(_config[kRouterConfigKeyTransitionDurationKey])
        {
            self.transitionDurationKey=_config[kRouterConfigKeyTransitionDurationKey];
        }
        
        if(_config[kRouterConfigKeyRoutingWithNewInstanceKey])
        {
            self.routingWithNewInstanceKey=_config[kRouterConfigKeyRoutingWithNewInstanceKey];
        }
        
        if(_config[kRouterConfigKeyRoutingWithMultipleInstanceKey])
        {
            self.routingWithMultipleInstanceKey=_config[kRouterConfigKeyRoutingWithMultipleInstanceKey];
        }
        
        if(_config[kRouterConfigKeyTransitionDuration])
        {
            self.transitionDuration=[_config[kRouterConfigKeyTransitionDuration] doubleValue];
        }
        
        if(_config[kRouterConfigKeyLogsDir])
        {
            self.logsDir=[NSString stringWithFormat:@"%@/%@",DOCUMENTS_PATH,_config[kRouterConfigKeyLogsDir]];
        }
        
        if(_config[kRouterConfigKeyKeepLogs])
        {
            self.shouldKeepLogs=[_config[kRouterConfigKeyKeepLogs] boolValue];
        }
        
        if(_config[kRouterConfigKeyUploadLogs])
        {
            self.shouldUploadLogs=[_config[kRouterConfigKeyUploadLogs] boolValue];
        }
        
        if(_config[kRouterConfigKeyLogsUploadURL])
        {
            self.logsUploadURL=_config[kRouterConfigKeyLogsUploadURL];
        }
        
        if(_config[kRouterConfigKeyLogsID])
        {
            self.logsID=_config[kRouterConfigKeyLogsID];
        }
        
        if(_config[kRouterConfigKeyLogsUploadContentKey])
        {
            self.logsUploadContentKey=_config[kRouterConfigKeyLogsUploadContentKey];
        }
        
        if(_config[kRouterConfigKeyLogsKeepDays])
        {
            self.logsKeepingDays=[_config[kRouterConfigKeyLogsKeepDays] intValue];
        }
    }
}


//保存配置文件
- (void)saveConfig
{
    if(!_config)
    {
        [self loadConfig];
    }
    
    [_config saveToFile:_profile];
}


#pragma -mark 注册

//注册视图(控制器),host为标识
+ (BOOL)registerClass:(Class)cls withHost:(NSString *)host
{
    if(cls && host)
    {
        return [self registerWithClassName:NSStringFromClass(cls) andHost:host];
    }
    
    return NO;
}


//通过类名注册视图控制器,host为标识
+ (BOOL)registerWithClassName:(NSString *)className andHost:(NSString *)host
{
    if(className && host)
    {
        KATRouter *router=[self sharedRouter];
        
        if(!router.classMap[host])//未注册该host
        {
            router.classMap[host]=className;
            
            //值容器表
            if(!router.valueMap[host])
            {
                router.valueMap[host]=[KATHashMap hashMap];
            }
            
            return YES;
        }
    }
    
    return NO;
}


//通过实例注册视图控制器,host为标识
+ (BOOL)registerInstance:(UIViewController *)vc withHost:(NSString *)host
{
    if(vc && host)
    {
        KATRouter *router=[self sharedRouter];
        
        if(!router.classMap[host])//未注册该host
        {
            router.classMap[host]=NSStringFromClass([vc class]);
        }
        
        //关联host
        objc_setAssociatedObject(vc, kRouterKeyHost, host, OBJC_ASSOCIATION_COPY_NONATOMIC);
        
        //挂钩支持屏幕方向
        [KATRouter hookSupportedOrientationsWithVC:vc];
        
        //释放旧的实例
        if(router.instanceMap[host])
        {
            //取消关联
            objc_removeAssociatedObjects(router.instanceMap[host]);
        }
        
        router.instanceMap[host]=vc;
        
        //多例处理
        NSRange range=[host rangeOfString:kRouterMultipleHostMark];
        
        if(range.length>0)
        {
            //多例共用一份值容器表
            NSString *oriHost=[host substringToIndex:range.location];//原始host
            
            //多例复制消息类型表
            KATArray<KATArray<NSString *> *> *types=[router.messageTypeMap allValues];
            
            for(KATArray<NSString *> *type in types)
            {
                if([type hasMember:oriHost])
                {
                    [type put:host];
                }
            }
        }
        else
        {
            //值容器表
            if(!router.valueMap[host])
            {
                router.valueMap[host]=[KATHashMap hashMap];
            }
        }
        
        return YES;
    }
    
    return NO;
}


//删除注册的视图控制器
+ (BOOL)removeRegisteredHost:(NSString *)host
{
    if(host)
    {
        KATRouter *router=[self sharedRouter];
        
        if(router.classMap[host])//注册过
        {
            //删除实例
            [self releaseInstanceWithHost:host];
            
            //删除类表
            [router.classMap deleteValueWithKey:host];
            
            //删除值表
            [router.valueMap deleteValueWithKey:host];
            
            //清除消息监听器
            [KATRouter removeObserverForAllMessageTypesWithHost:host];
            
            return YES;
        }
    }
    
    return NO;
}



#pragma -mark 标签栏

//设置标签栏
+ (void)setTabBar:(KATTabBar *)tabBar
{
    KATRouter *router=[self sharedRouter];
    
    if(tabBar==router.tabBar)
    {
        return;
    }
    
    if(router.tabBar)
    {
        [router.tabBar removeFromSuperview];
    }
    
    router.tabBar=tabBar;
    
    [router.window addSubview:router.tabBar];
    
    if(router.tabBar)
    {
//        [router.tabBar selectWithIndex:0];
    }
}


//设置是否自动隐藏标签栏(非关联标签栏的host)(默认为否)
+ (void)setIsAutoHidingTabBar:(BOOL)hidding
{
    KATRouter *router=[self sharedRouter];
    
    router.isAutoHidingTabBar=hidding;
}


//隐藏标签栏
+ (void)hideTabBar
{
    KATRouter *router=[self sharedRouter];
    
    if(router.tabBar)
    {
        [router.tabBar hide];
    }
}


//显示标签栏
+ (void)showTabBar
{
    KATRouter *router=[self sharedRouter];
    
    if(router.tabBar)
    {
        [router.tabBar show];
    }
}


//刷新标签栏
+ (void)updateTabBar
{
    KATRouter *router=[self sharedRouter];
    
    if(router.tabBar)
    {
        [router.tabBar update];
    }
}


//选中标签
+ (void)selectTabWithIndex:(unsigned)index
{
    KATRouter *router=[self sharedRouter];
    
    if(router.tabBar)
    {
        [router.tabBar selectWithIndex:index];
    }
}


//选中标签
+ (void)selectTabWithHost:(NSString *)host
{
    KATRouter *router=[self sharedRouter];
    
    if(router.tabBar)
    {
        [router.tabBar selectWithHost:host];
    }
}


//添加徽标
+ (void)addBadgeToTabWithIndex:(unsigned)index
{
    KATRouter *router=[self sharedRouter];
    
    if(router.tabBar)
    {
        [router.tabBar addBadgeWithIndex:index];
    }
}


//添加徽标
+ (void)addBadgeToTabWithHost:(NSString *)host
{
    KATRouter *router=[self sharedRouter];
    
    if(router.tabBar)
    {
        [router.tabBar addBadgeWithHost:host];
    }
}


//删除徽标
+ (void)removeBadgeFromTabWithIndex:(unsigned)index
{
    KATRouter *router=[self sharedRouter];
    
    if(router.tabBar)
    {
        [router.tabBar removeBadgeWithIndex:index];
    }
}


//删除徽标
+ (void)removeBadgeFromTabWithHost:(NSString *)host
{
    KATRouter *router=[self sharedRouter];
    
    if(router.tabBar)
    {
        [router.tabBar removeBadgeWithHost:host];
    }
}


//清除所有的徽标
+ (void)clearBadgesFromTabBar
{
    KATRouter *router=[self sharedRouter];
    
    if(router.tabBar)
    {
        [router.tabBar clearBadges];
    }
}


//获取标签栏
+ (KATTabBar *)getTabBar
{
    KATRouter *router=[self sharedRouter];
    
    return router.tabBar;
}


//获取tab栏选中的host
+ (NSString *)hostInSelectedTab
{
    KATRouter *router=[self sharedRouter];
    
    if(router.tabBar)
    {
        return [router.tabBar selectedHost];
    }
    
    return nil;
}


//获取tab栏选中的URI
+ (NSString *)URIInSelectedTab
{
    KATRouter *router=[self sharedRouter];
    
    if(router.tabBar)
    {
        return [router.tabBar selectedURI];
    }
    
    return nil;
}


#pragma -mark 导航栏

//设置导航栏
+ (void)setNavBar:(KATNavBar *)navBar
{
    KATRouter *router=[self sharedRouter];
    
    if(navBar==router.navBar)
    {
        return;
    }
    
    if(router.navBar)
    {
        [router.navBar removeFromSuperview];
    }
    
    router.navBar=navBar;
    
    [router.window addSubview:router.navBar];
}


//隐藏导航栏
+ (void)hideNavBar
{
    KATRouter *router=[self sharedRouter];
    
    if(router.navBar)
    {
        [router.navBar hide];
    }
}


//显示导航栏
+ (void)showNavBar
{
    KATRouter *router=[self sharedRouter];
    
    if(router.navBar)
    {
        [router.navBar show];
    }
}


//刷新导航栏
+ (void)updateNavBar
{
    KATRouter *router=[self sharedRouter];
    
    if(router.navBar)
    {
        [router.navBar update];
    }
}


//获取导航栏
+ (KATNavBar *)getNavBar
{
    KATRouter *router=[self sharedRouter];
    
    return router.navBar;
}


#pragma -mark 横竖屏

//设置默认屏幕方向是否为横屏
+ (void)setDefaultOrientationLandscape:(BOOL)isLandscapeDefault
{
    KATRouter *router=[self sharedRouter];
    
    router.isLandscapeOrientationDefault=isLandscapeDefault;
}


//添加竖屏方向的host数组
+ (void)addPortraitOrientationHosts:(KATArray<NSString *> *)hosts
{
    if(hosts && hosts.length>0)
    {
        KATRouter *router=[self sharedRouter];
        
        for(NSString *host in hosts)
        {
            [router.portraitOrientationHosts putWithKey:host andValue:host];
        }
    }
}


//添加竖屏方向的host
+ (void)addPortraitOrientationHost:(NSString *)host
{
    if(host)
    {
        KATRouter *router=[self sharedRouter];
    
        [router.portraitOrientationHosts putWithKey:host andValue:host];
    }
}


//删除竖屏方向的host
+ (void)removePortraitOrientationHost:(NSString *)host
{
    if(host)
    {
        KATRouter *router=[self sharedRouter];
        
        [router.portraitOrientationHosts deleteValueWithKey:host];
    }
}


//清除竖屏方向的host
+ (void)clearPortraitOrientationHosts
{
    KATRouter *router=[self sharedRouter];
        
    [router.portraitOrientationHosts clear];
}


//添加横屏方向的host数组
+ (void)addLandscapeOrientationHosts:(KATArray<NSString *> *)hosts
{
    if(hosts && hosts.length>0)
    {
        KATRouter *router=[self sharedRouter];
        
        for(NSString *host in hosts)
        {
            [router.landscapeOrientationHosts putWithKey:host andValue:host];
        }
    }
}


//添加横屏方向的host
+ (void)addLandscapeOrientationHost:(NSString *)host
{
    if(host)
    {
        KATRouter *router=[self sharedRouter];
    
        [router.landscapeOrientationHosts putWithKey:host andValue:host];
    }
}


//删除横屏方向的host
+ (void)removeLandscapeOrientationHost:(NSString *)host
{
    if(host)
    {
        KATRouter *router=[self sharedRouter];
        
        [router.landscapeOrientationHosts deleteValueWithKey:host];
    }
}


//清除横屏方向的host
+ (void)clearLandscapeOrientationHosts
{
    KATRouter *router=[self sharedRouter];
    
    [router.landscapeOrientationHosts clear];
}


//添加自由方向的host数组
+ (void)addFreeOrientationHosts:(KATArray<NSString *> *)hosts
{
    if(hosts && hosts.length>0)
    {
        KATRouter *router=[self sharedRouter];
        
        for(NSString *host in hosts)
        {
            [router.freeOrientationHosts putWithKey:host andValue:host];
        }
    }
}


//添加自由方向的host
+ (void)addFreeOrientationHost:(NSString *)host
{
    if(host)
    {
        KATRouter *router=[self sharedRouter];
        
        [router.freeOrientationHosts putWithKey:host andValue:host];
    }
}


//删除自由方向的host
+ (void)removeFreeOrientationHost:(NSString *)host
{
    if(host)
    {
        KATRouter *router=[self sharedRouter];
        
        [router.freeOrientationHosts deleteValueWithKey:host];
    }
}


//清除自由方向的host
+ (void)clearFreeOrientationHosts
{
    KATRouter *router=[self sharedRouter];
    
    [router.freeOrientationHosts clear];
}


//设置方向改变系统通知处理(内部方法)
- (void)deviceOrientationDidChange
{
    if([KATAppUtil currentOrientation]!=UIInterfaceOrientationPortrait && [KATAppUtil currentOrientation]!=UIInterfaceOrientationPortraitUpsideDown && [KATAppUtil currentOrientation]!=UIInterfaceOrientationLandscapeLeft && [KATAppUtil currentOrientation]!=UIInterfaceOrientationLandscapeRight)
    {
        return;
    }
    
    if([KATAppUtil topViewController]!=_rootVC && [KATRouter topViewController]!=[KATAppUtil topViewController])
    {
        if(MAX([KATAppUtil topViewController].view.bounds.size.width, [KATAppUtil topViewController].view.bounds.size.height)>MAX(SCREEN_WIDTH, SCREEN_HEIGHT)-0.5 || MIN([KATAppUtil topViewController].view.bounds.size.width, [KATAppUtil topViewController].view.bounds.size.height)>MIN(SCREEN_WIDTH, SCREEN_HEIGHT)-0.5)//全屏VC不处理
        {
            return;
        }
    }
    
    if(_showingHost)
    {
        //先判断是否为自由方向
        if([_freeOrientationHosts getValueWithKey:_showingHost])
        {
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^
            {
                if(_navBar)//更新nav栏
                {
                    [_navBar update];
                }
            
                if(_tabBar)//更新tab栏
                {
                    [_tabBar update];
                }
            });
            
            return;
        }
        
        [_router adjustOritation];
        
//        //是否为横屏
//        BOOL isLandscape=_isLandscapeOrientationDefault;
//
//        if(_isLandscapeOrientationDefault)//默认横屏
//        {
//            if([_portraitOrientationHosts getValueWithKey:_showingHost])
//            {
//                isLandscape=NO;
//            }
//            else
//            {
//                isLandscape=YES;
//            }
//        }
//        else//默认竖屏
//        {
//            if([_landscapeOrientationHosts getValueWithKey:_showingHost])
//            {
//                isLandscape=YES;
//            }
//            else
//            {
//                isLandscape=NO;
//            }
//        }
//
//        if(isLandscape)//横屏处理
//        {
//            if([KATAppUtil currentOrientation]==UIInterfaceOrientationLandscapeRight || [KATAppUtil currentOrientation]==UIInterfaceOrientationLandscapeLeft)//当前横屏
//            {
//                //不处理
//            }
//            else//当前非横屏
//            {
//                //强转横屏
//                [KATAppUtil setOrientation:UIInterfaceOrientationLandscapeRight];
//            }
//        }
//        else//竖屏处理
//        {
//            if([KATAppUtil currentOrientation]==UIInterfaceOrientationPortrait)//当前竖屏
//            {
//                //不处理
//            }
//            else//当前非竖屏
//            {
//                //强转竖屏
//                [KATAppUtil setOrientation:UIInterfaceOrientationPortrait];
//            }
//        }
    }
    
}


#pragma -mark 日志记录


//设置日志保存目录
+ (void)setLogsDirectory:(NSString *)dir
{
    KATRouter *router=[self sharedRouter];
    
    if(!router.config[kRouterConfigKeyLogsDir])//不存在则设置
    {
        [self changeLogsDirectory:dir];
    }
}


//更改日志保存目录
+ (void)changeLogsDirectory:(NSString *)dir
{
    KATRouter *router=[self sharedRouter];
    
    router.logsDir=[NSString stringWithFormat:@"%@/%@",DOCUMENTS_PATH,dir];
    
    //创建目录
    [KATFileUtil createDir:router.logsDir];
    
    //保存到配置文件
    router.config[kRouterConfigKeyLogsDir]=dir;
    
    [router saveConfig];
}


//获取历史日志
+ (KATTreeMap<KATHashMap *> *)getHistoryLogs
{
    KATRouter *router=[self sharedRouter];
    
    return router.historyLogs;
}


//获取当日日志
+ (KATHashMap *)getDayLogs
{
    KATRouter *router=[self sharedRouter];
    
    return router.dayLogs;
}


//获取本次app使用的日志
+ (KATHashMap *)getAppLog
{
    KATRouter *router=[self sharedRouter];
    
    return router.appLog;
}


//获取当前host的日志
+ (KATHashMap *)getHostLog
{
    KATRouter *router=[self sharedRouter];
    
    return router.hostLog;
}


//清空日志
+ (void)clearLogs
{
    KATRouter *router=[self sharedRouter];
    
    if(router.logsDir)
    {
        //删除目录
        [KATFileUtil removeFile:router.logsDir];
        
        //创建目录
        if(![KATFileUtil existsFile:router.logsDir])
        {
            if([KATFileUtil createDir:router.logsDir])
            {
                
            }
            else
            {
                router.logsDir=nil;
            }
        }
    }
}


//设置是否保存日志(默认保存日志)
+ (void)setShouldKeepLogs:(BOOL)keep
{
    KATRouter *router=[self sharedRouter];
    
    if(!router.config[kRouterConfigKeyKeepLogs])//不存在则设置
    {
        [self changeShouldKeepLogs:keep];
    }
}


//更改是否保存日志(默认保存日志)
+ (void)changeShouldKeepLogs:(BOOL)keep
{
    KATRouter *router=[self sharedRouter];
    
    router.shouldKeepLogs=keep;
    
    //保存到配置文件
    router.config[kRouterConfigKeyKeepLogs]=[NSString stringWithFormat:@"%i",router.shouldKeepLogs];
    
    [router saveConfig];
}


//设置日志保留时间(单位日,默认60日)
+ (void)setLogsKeepingDays:(int)days
{
    KATRouter *router=[self sharedRouter];
    
    if(!router.config[kRouterConfigKeyLogsKeepDays])//不存在则设置
    {
        [self changeLogsKeepingDays:days];
    }
}


//更改日志保留时间(单位日,默认60日，最多保存1000日)
+ (void)changeLogsKeepingDays:(int)days
{
    KATRouter *router=[self sharedRouter];
    
    if(days<=0)
    {
        days=1;
    }
    
    if(days>1000)
    {
        days=1000;
    }
    
    router.logsKeepingDays=days;
    
    //保存到配置文件
    router.config[kRouterConfigKeyLogsKeepDays]=[NSString stringWithFormat:@"%i",router.logsKeepingDays];
    
    [router saveConfig];
}


//获取日志上传地址
+ (NSString *)getLogsUploadURL
{
    KATRouter *router=[self sharedRouter];
    
    return router.logsUploadURL;
}


//设置日志上传地址
+ (void)setLogsUploadURL:(NSString *)URL
{
    KATRouter *router=[self sharedRouter];
    
    if(!router.config[kRouterConfigKeyLogsUploadURL])//不存在则设置
    {
        [self changeLogsUploadURL:URL];
    }
}


//更改日志上传地址
+ (void)changeLogsUploadURL:(NSString *)URL
{
    KATRouter *router=[self sharedRouter];
    
    router.logsUploadURL=URL;
    
    //保存到配置文件
    router.config[kRouterConfigKeyLogsUploadURL]=router.logsUploadURL;
    
    [router saveConfig];
}


//获取日志用户ID
+ (NSString *)getLogsID
{
    KATRouter *router=[self sharedRouter];
    
    return router.logsID;
}


//设置日志的用户ID(只设置一次)
+ (void)setLogsID:(NSString *)ID
{
    KATRouter *router=[self sharedRouter];
    
    if(!router.config[kRouterConfigKeyLogsID])//不存在则设置
    {
        [self changeLogsID:ID];
    }
}


//更改日志的用户ID
+ (void)changeLogsID:(NSString *)ID
{
    KATRouter *router=[self sharedRouter];
    
    router.logsID=ID;
    
    //保存到配置文件
    router.config[kRouterConfigKeyLogsID]=router.logsID;
    
    [router saveConfig];
    
    //先保存host
    [router _saveHostLog];
    
    //设置离开时间
    router.appLog[kRouterLogsKeyAppLeaveTime]=[NSString stringWithFormat:@"%lli",[KATDateUtil now]/DATE_TIME_SECOND];
    
    //计算持续时间
    KATDateTime enterTime=[router.appLog[kRouterLogsKeyAppEnterTime] longLongValue]*DATE_TIME_SECOND;
    KATDateTime leaveTime=[router.appLog[kRouterLogsKeyAppLeaveTime] longLongValue]*DATE_TIME_SECOND;
    long long seconds=[KATDateUtil difSecondsFromTime:enterTime toTime:leaveTime];
    
    //设置持续时间
    router.appLog[kRouterLogsKeyAppDuration]=[NSString stringWithFormat:@"%lli",seconds];
    
    //是否保存
    if(router.shouldKeepLogs)
    {
        //保存当日的日志
        [router.dayLogs saveToFile:[NSString stringWithFormat:@"%@/%@.%@",router.logsDir,router.dayLogs[kRouterLogsKeyDate],kRouterLogFileSuffix]];
    }
    
    //保存后置空
    router.appLog=nil;
    
    //保存任务
    [router saveMissions];
    
    //加载host日志
    [router _loadHostLog];
}


//获取日志上传的内容属性名(只设置一次)
+ (NSString *)getLogsUploadContentKey
{
    KATRouter *router=[self sharedRouter];
    
    return router.logsUploadContentKey;
}


//设置日志上传的内容属性名(只设置一次)
+ (void)setLogsUploadContentKey:(NSString *)key
{
    KATRouter *router=[self sharedRouter];
    
    if(!router.config[kRouterConfigKeyLogsUploadContentKey])//不存在则设置
    {
        [self changeLogsUploadContentKey:key];
    }
}


//更改日志上传的内容属性名
+ (void)changeLogsUploadContentKey:(NSString *)key
{
    KATRouter *router=[self sharedRouter];
    
    router.logsUploadContentKey=key;
    
    //保存到配置文件
    router.config[kRouterConfigKeyLogsUploadContentKey]=router.logsUploadContentKey;
    
    [router saveConfig];
}


//获取日志上传的附加信息(只设置一次)
+ (KATHashMap *)getLogsUploadExtra
{
    KATRouter *router=[self sharedRouter];
    
    return router.logsUploadExtra;
}


//设置日志上传的附加信息(只设置一次)
+ (void)setLogsUploadExtra:(KATHashMap *)extra
{
    KATRouter *router=[self sharedRouter];
    
    if(!router.logsUploadExtra)
    {
        [self changeLogsUploadExtra:extra];
    }
}


//更改日志上传的附加信息
+ (void)changeLogsUploadExtra:(KATHashMap *)extra
{
    KATRouter *router=[self sharedRouter];
    
    router.logsUploadExtra=extra;
}


//设置是否上传日志
+ (void)setShouldUploadLogs:(BOOL)upload
{
    KATRouter *router=[self sharedRouter];
    
    if(!router.config[kRouterConfigKeyUploadLogs])//不存在则设置
    {
        [self changeShouldUploadLogs:upload];
    }
}


//更改是否上传日志
+ (void)changeShouldUploadLogs:(BOOL)upload
{
    KATRouter *router=[self sharedRouter];
    
    router.shouldUploadLogs=upload;
    
    //保存到配置文件
    router.config[kRouterConfigKeyUploadLogs]=[NSString stringWithFormat:@"%i",router.shouldUploadLogs];
    
    [router saveConfig];
}


//设置日志上传后回调动作，返回是否成功(默认为空，为空时，若有数据返回，则认为上传成功)
+ (void)setLogsDidUploadAction:(BOOL (^)(NSString *feeback))action
{
    KATRouter *router=[self sharedRouter];
    
    router.logsDidUploadAction=action;
}


//更新日志(内部方法，用于清理过期的日志)
- (void)updateLogs
{
    //计算有最早效日期
    NSString *vaildDay=[NSString stringWithFormat:@"%i",[KATDateUtil theDayBefore:_logsKeepingDays onDay:[KATDateUtil today]]];
    
    KATArray<NSString *> *logFiles=[KATFileUtil filesInDir:_logsDir];
    
    for(NSString *file in logFiles)
    {
        if([file hasSuffix:kRouterLogFileSuffix])//日志文件后缀
        {
            //超过有效期
            if([vaildDay compare:file]==NSOrderedDescending)
            {
                //删除
                [KATFileUtil removeFile:[NSString stringWithFormat:@"%@/%@",_logsDir,file]];
            }
        }
    }
}


//加载日志(内部方法，初始化时)
- (void)loadLogs
{
    dispatch_async(_queueLogsSaving, ^
    {
        //加载配置文件
        [self loadConfig];
        
        if(!_logsDir)//没有保存，则初始化默认值
        {
            [KATRouter changeLogsDirectory:@"router_logs"];
        }
        
        if(_logsKeepingDays<=0)//没有保存，则初始化默认值
        {
            [KATRouter changeLogsKeepingDays:60];
        }
        
        //清理过期日志
        [self updateLogs];
        
        //加载历史数据
        self.historyLogs=[KATTreeMap treeMap];
           
        KATArray<NSString *> *logFiles=[KATFileUtil filesInDir:_logsDir];
        
        for(NSString *file in logFiles)
        {
            if([file hasSuffix:kRouterLogFileSuffix])//日志文件后缀
            {
                KATHashMap *log=[KATHashMap hashMapWithFile:[NSString stringWithFormat:@"%@/%@",_logsDir,file]];
                
                [_historyLogs putWithKey:[file stringByReplacingOccurrencesOfString:[NSString stringWithFormat:@".%@",kRouterLogFileSuffix] withString:@""] andValue:log];
            }
        }
        
        //今日字符串
        NSString *todayStr=[NSString stringWithFormat:@"%i",[KATDateUtil today]];
        
        //今日日志
        self.dayLogs=_historyLogs[todayStr];
        
        if(!_dayLogs)//不存在则创建
        {
            self.dayLogs=[KATHashMap hashMap];
            
            //设置日期
            _dayLogs[kRouterLogsKeyDate]=todayStr;
            
            //设置日志记录数组
            _dayLogs[kRouterLogsKeyLogs]=[KATArray array];
            
            //添加到历史
            _historyLogs[todayStr]=_dayLogs;
        }
        
        //加载任务
        [self loadMissions];
    });
}


//加载本次app使用日志(内部方法)
- (void)_loadAppLog
{
    if(!_appLog)
    {
        //本次app使用日志
        self.appLog=[KATHashMap hashMap];
        
        //设置编号
        long long logNum=0;
        
        KATArray *appLogs=_dayLogs[kRouterLogsKeyLogs];
        
        if(appLogs.length>0)//当日有其他记录
        {
            //当日最近一条日志
            KATHashMap *logMap=[appLogs lastMember];
            
            //最近日志的编号
            long long lastNum=[logMap[kRouterLogsKeyLogNum] longLongValue]%_logNumberMod;
            
            logNum=lastNum+1;
        }
        
        _appLog[kRouterLogsKeyLogNum]=[NSString stringWithFormat:@"%lli",[KATDateUtil today]*_logNumberMod+logNum];
        
        //设置用户ID
        _appLog[kRouterLogsKeyID]=_logsID;
        
        //设置日期
        _appLog[kRouterLogsKeyLogDate]=[NSString stringWithFormat:@"%i",[KATDateUtil today]];
        
        //设置host访问数组
        _appLog[kRouterLogsKeyHosts]=[KATArray array];
        
        //设置状态
        _appLog[kRouterLogsKeyLogStatus]=[NSString stringWithFormat:@"%i",ROUTER_LOG_STATUS_UNKNOWN];
        
        //设置进入时间
        _appLog[kRouterLogsKeyAppEnterTime]=[NSString stringWithFormat:@"%lli",[KATDateUtil now]/DATE_TIME_SECOND];
        
        //添加到今日日志
        [appLogs put:_appLog];
    }
}


//保存本次app使用日志(内部方法)
- (void)_saveAppLog
{
    dispatch_async(_queueLogsSaving, ^
    {
        //先保存host
        [self _saveHostLog];
        
        //设置离开时间
        _appLog[kRouterLogsKeyAppLeaveTime]=[NSString stringWithFormat:@"%lli",[KATDateUtil now]/DATE_TIME_SECOND];
        
        //计算持续时间
        KATDateTime enterTime=[_appLog[kRouterLogsKeyAppEnterTime] longLongValue]*DATE_TIME_SECOND;
        KATDateTime leaveTime=[_appLog[kRouterLogsKeyAppLeaveTime] longLongValue]*DATE_TIME_SECOND;
        long long seconds=[KATDateUtil difSecondsFromTime:enterTime toTime:leaveTime];
        
        //设置持续时间
        _appLog[kRouterLogsKeyAppDuration]=[NSString stringWithFormat:@"%lli",seconds];
        
        //是否保存
        if(_shouldKeepLogs)
        {
            //保存当日的日志
            [_dayLogs saveToFile:[NSString stringWithFormat:@"%@/%@.%@",_logsDir,_dayLogs[kRouterLogsKeyDate],kRouterLogFileSuffix]];
        }
        
        //是否上传
        if(_shouldUploadLogs && _logsUploadURL)
        {
            dispatch_async(_queueLogsUploading, ^
            {
                //需要上传的内容
                KATHashMap *data=[KATHashMap hashMap];
                data.isJsonDescription=YES;
                
                //添加附加信息
                [data putWithMap:_logsUploadExtra];
                
                //日志数据内容
                KATArray<KATHashMap *> *content=[KATArray array];
                
                //遍历历史记录
                KATArray *history=[_historyLogs allValues];
                
                for(KATHashMap *dayLogs in history)
                {
                    //遍历当日
                    KATArray *logs=dayLogs[kRouterLogsKeyLogs];
                    
                    for(KATHashMap *log in logs)
                    {
                        int status=[log[kRouterLogsKeyLogStatus] intValue];
                        
                        if(status==ROUTER_LOG_STATUS_UNKNOWN)//未上传
                        {
                            //添加到需要上传的数据内容
                            [content put:log];
                        }
                    }
                }
                
                if(content.length>0)//上传内容非空，需要上传
                {
                    //添加内容
                    data[_logsUploadContentKey]=content;
                    
                    //http请求
                    KATHttpRequest *request=[KATHttpRequest request];
                    
                    //是否上传成功
                    BOOL success=NO;
                    
                    //返回结果
                    NSString *feeback=[request postTextWithUrl:_logsUploadURL andSendText:[data description]];
                    
                    //成功条件
                    if(_logsDidUploadAction)
                    {
                        success=_logsDidUploadAction(feeback);
                    }
                    else
                    {
                        if(feeback)
                        {
                            success=YES;
                        }
                        else
                        {
                            success=NO;
                        }
                    }
                    
                    if(success)//上传成功
                    {
                        //日志上传状态改变
                        
                        //遍历历史记录
                        KATArray *history=[_historyLogs allValues];
                        
                        for(KATHashMap *dayLogs in history)
                        {
                            //遍历当日
                            KATArray *logs=dayLogs[kRouterLogsKeyLogs];
                            
                            for(KATHashMap *log in logs)
                            {
                                //设置状态
                                log[kRouterLogsKeyLogStatus]=[NSString stringWithFormat:@"%i",ROUTER_LOG_STATUS_UPLOADED];
                            }
                            
                            //保存该日的日志
                            [dayLogs saveToFile:[NSString stringWithFormat:@"%@/%@.%@",_logsDir,dayLogs[kRouterLogsKeyDate],kRouterLogFileSuffix]];
                        }
                    }
                }
                
            });
        }
        
        //保存后置空
        self.appLog=nil;
        
        //保存任务
        [self saveMissions];
    });
}


//加载host记录(内部方法)
- (void)_loadHostLog
{
    dispatch_async(_queueLogsSaving, ^
    {
        if(!_hostLog)
        {
            if(!_appLog)//首次打开app可能先有跳转后触发appLog加载事件
            {
                [self _loadAppLog];
            }
            
            //创建host日志
            self.hostLog=[KATHashMap hashMap];
        
            //设置属性
            _hostLog[kRouterLogsKeyHost]=_showingHost;
            _hostLog[kRouterLogsKeyHostURI]=_lastURI;
            _hostLog[kRouterLogsKeyHostEnterTime]=[NSString stringWithFormat:@"%lli",[KATDateUtil now]/DATE_TIME_SECOND];
            _hostLog[kRouterLogsKeyEvents]=[KATArray array];
            
            //添加到app日志
            [(KATArray *)_appLog[kRouterLogsKeyHosts] put:_hostLog];
        }
    });
}


//保存host记录(内部方法)
- (void)_saveHostLog
{
    if(_hostLog)
    {
        //设置离开时间
        _hostLog[kRouterLogsKeyHostLeaveTime]=[NSString stringWithFormat:@"%lli",[KATDateUtil now]/DATE_TIME_SECOND];
        
        //计算持续时间
        KATDateTime enterTime=[_hostLog[kRouterLogsKeyAppEnterTime] longLongValue]*DATE_TIME_SECOND;
        KATDateTime leaveTime=[_hostLog[kRouterLogsKeyAppLeaveTime] longLongValue]*DATE_TIME_SECOND;
        long long seconds=[KATDateUtil difSecondsFromTime:enterTime toTime:leaveTime];
        
        //设置持续时间
        _hostLog[kRouterLogsKeyHostDuration]=[NSString stringWithFormat:@"%lli",seconds];
        
        //置空
        self.hostLog=nil;
    }
}


//标记事件(全参数)
+ (void)markEvent:(NSString *)event withTag:(long long)tag andMessage:(NSString *)msg
{
    if(event)
    {
        KATRouter *router=[KATRouter sharedRouter];
        
        if(!router.hostLog)
        {
            [router _loadHostLog];
        }
        
        if(!msg)
        {
            msg=@"";
        }
        
        //构造事件
        KATHashMap *eventLog=[KATHashMap hashMapWithCapacity:10 andMaxUsage:70];
        eventLog.isJsonDescription=YES;
        
        //设置内容
        eventLog[kRouterLogsKeyEvent]=event;
        eventLog[kRouterLogsKeyEventTag]=[NSNumber numberWithLongLong:tag];
        eventLog[kRouterLogsKeyEventMessage]=msg;
        eventLog[kRouterLogsKeyEventTime]=[NSString stringWithFormat:@"%lli",[KATDateUtil now]/10];
        
        //添加到host日志
        [(KATArray *)_router.hostLog[kRouterLogsKeyEvents] put:eventLog];
        
        //执行任务
        [router executeCountMissionsWithEvent:event];
    }
}


//标记事件
+ (void)markEvent:(NSString *)event withTag:(long long)tag
{
    [self markEvent:event withTag:tag andMessage:@""];
}


//标记事件
+ (void)markEvent:(NSString *)event withMessage:(NSString *)msg
{
    [self markEvent:event withTag:0 andMessage:msg];
}


//标记事件
+ (void)markEvent:(NSString *)event
{
    [self markEvent:event withTag:0 andMessage:@""];
}



#pragma -mark 日志分析

//当日的app的使用时长(单位:秒)
+ (long long)durationByDayUsing
{
    return [KATRouter durationByDayUsingWithIDs:nil];
}


//当日指定用户的app的使用时长(单位:秒)(IDs为空时返回所有的)
+ (long long)durationByDayUsingWithIDs:(KATArray<NSString *> *)IDs
{
    KATRouter *router=[self sharedRouter];
    
    //计算持续时间
    long long seconds=0;
    
    //当日log数组
    KATArray *logs=router.dayLogs[kRouterLogsKeyLogs];
    
    if(logs && logs.length>0)
    {
        for(int i=0;i<logs.length;i++)
        {
            KATHashMap *log=logs[i];
            
            //用户过滤
            if(IDs && IDs.length>0)
            {
                if(log[kRouterLogsKeyID] && [IDs hasMember:log[kRouterLogsKeyID]])
                {
                    //找到
                }
                else
                {
                    continue;
                }
            }
            
            //迄止时间
            KATDateTime beginTime=[log[kRouterLogsKeyAppEnterTime] longLongValue]*DATE_TIME_SECOND;
            KATDateTime endTime=[log[kRouterLogsKeyAppLeaveTime] longLongValue]*DATE_TIME_SECOND;
            
            if(log==router.appLog)//本次log，还没有记录结束时间
            {
                endTime=[KATDateUtil now];
            }
            
            //迄止日期
            int beginDay=beginTime/DATE_TIME_DAY;
            int endDay=endTime/DATE_TIME_DAY;
            
            if(beginDay>=[KATDateUtil today])//从今天开始(开始和结束日期不可能在今天之后)
            {
                seconds+=[KATDateUtil difSecondsFromTime:beginTime toTime:endTime];
            }
            else if(endDay>=[KATDateUtil today])//开始日期是今天之前，结束日期在今天
            {
                seconds+=[KATDateUtil difSecondsFromTime:[KATDateUtil today]*DATE_TIME_DAY toTime:endTime];
            }
            else//开始和结束时间都在今天之前
            {
                //不作计算
            }
        }
    }
    
    return seconds;
}


//本次app的使用时长(单位:秒)
+ (long long)durationByAppUsing
{
    KATRouter *router=[self sharedRouter];
    
    //计算持续时间
    KATDateTime beginTime=[router.appLog[kRouterLogsKeyAppEnterTime] longLongValue]*DATE_TIME_SECOND;
    long long seconds=[KATDateUtil difSecondsFromTime:beginTime toTime:[KATDateUtil now]];
    
    return seconds;
}


//在当前host停留的时长(单位:秒)
+ (long long)durationByHostUsing
{
    KATRouter *router=[self sharedRouter];
    
    //计算持续时间
    KATDateTime beginTime=[router.hostLog[kRouterLogsKeyHostEnterTime] longLongValue]*DATE_TIME_SECOND;
    long long seconds=[KATDateUtil difSecondsFromTime:beginTime toTime:[KATDateUtil now]];
    
    return seconds;
}


//获取最早一次日志到现在的天数(没有则返回负数)
+ (int)daysFromFirstLog
{
    KATRouter *router=[self sharedRouter];
    
    //首日日志
    KATHashMap *dayLogs=[router.historyLogs firstValue];
    
    //当日的日志
    KATArray<KATHashMap *> *logs=dayLogs[kRouterLogsKeyLogs];
    
    if(logs && logs.length>0)
    {
        for(int i=0;i<logs.length;i++)
        {
            KATHashMap *log=logs[i];
            
            if(log!=router.appLog)//非本次app记录
            {
                int lastDay=[log[kRouterLogsKeyDate] intValue];
                
                return [KATDateUtil daysPastFrom:lastDay to:[KATDateUtil today]];
            }
        }
    }
    
    return -1;
}


//获取最近一次日志到现在的天数(没有则返回负数)
+ (int)daysFromLastLog
{
    KATRouter *router=[self sharedRouter];
    
    //尾日日志
    KATHashMap *dayLogs=[router.historyLogs lastValue];
    
    //当日的日志
    KATArray<KATHashMap *> *logs=dayLogs[kRouterLogsKeyLogs];
    
    if(logs && logs.length>0)
    {
        //从后往前遍历
        for(int i=logs.length-1;i>=0;i--)
        {
            KATHashMap *log=logs[i];
            
            if(log!=router.appLog)//非本次app记录
            {
                int lastDay=[log[kRouterLogsKeyDate] intValue];
                
                return [KATDateUtil daysPastFrom:lastDay to:[KATDateUtil today]];
            }
        }
    }
    
    //若当日日志没有找到，则找次日的
    KATArray<KATHashMap *> *history=[router.historyLogs allValues];
    
    if(history.length>1)
    {
        dayLogs=history[history.length-2];
        
        //该日的日志
        logs=dayLogs[kRouterLogsKeyLogs];
        
        if(logs && logs.length>0)
        {
            //从后往前遍历
            for(int i=logs.length-1;i>=0;i--)
            {
                KATHashMap *log=logs[i];
                
                if(log!=router.appLog)//非本次app记录
                {
                    int lastDay=[log[kRouterLogsKeyDate] intValue];
                    
                    return [KATDateUtil daysPastFrom:lastDay to:[KATDateUtil today]];
                }
            }
        }
    }
    
    return -1;
}



///获取最早一次日志到现在的秒数(从日志的开始时间计算，没有则返回负数)
+ (long long)secondsFromFirstLog
{
    KATRouter *router=[self sharedRouter];
    
    //首日日志
    KATHashMap *dayLogs=[router.historyLogs firstValue];
    
    //当日的日志
    KATArray<KATHashMap *> *logs=dayLogs[kRouterLogsKeyLogs];
    
    if(logs && logs.length>0)
    {
        KATHashMap *log=[logs firstMember];
        
        long long enterTime=[log[kRouterLogsKeyAppEnterTime] longLongValue]*DATE_TIME_SECOND;
        
        return [KATDateUtil difSecondsFromTime:enterTime toTime:[KATDateUtil now]];
    }
    
    return -1;
}


//获取最近一次日志到现在的秒数(从日志的结束时间计算，没有则返回负数)
+ (long long)secondsFromLastLog
{
    KATRouter *router=[self sharedRouter];
    
    //尾日日志
    KATHashMap *dayLogs=[router.historyLogs lastValue];
    
    //当日的日志
    KATArray<KATHashMap *> *logs=dayLogs[kRouterLogsKeyLogs];
    
    if(logs && logs.length>0)
    {
        //从后往前遍历
        for(int i=logs.length-1;i>=0;i--)
        {
            KATHashMap *log=logs[i];
            
            if(log!=router.appLog)//非本次app记录
            {
                long long leaveTime=[log[kRouterLogsKeyAppLeaveTime] longLongValue]*DATE_TIME_SECOND;
                
                return [KATDateUtil difSecondsFromTime:leaveTime toTime:[KATDateUtil now]];
            }
        }
    }
    
    //若当日日志没有找到，则找次日的
    KATArray<KATHashMap *> *history=[router.historyLogs allValues];
    
    if(history.length>1)
    {
        dayLogs=history[history.length-2];
        
        //该日的日志
        logs=dayLogs[kRouterLogsKeyLogs];
        
        if(logs && logs.length>0)
        {
            //从后往前遍历
            for(int i=logs.length-1;i>=0;i--)
            {
                KATHashMap *log=logs[i];
                
                if(log!=router.appLog)//非本次app记录
                {
                    long long leaveTime=[log[kRouterLogsKeyAppLeaveTime] longLongValue]*DATE_TIME_SECOND;
                    
                    return [KATDateUtil difSecondsFromTime:leaveTime toTime:[KATDateUtil now]];
                }
            }
        }
    }
    
    return -1;
}



//获取最近一次host日志到现在的天数(没有则返回负数)
+ (int)daysFromLastUsingWithHost:(NSString *)host
{
    if(!host)
    {
        return -1;
    }
    
    KATRouter *router=[self sharedRouter];
    
    //获取历史记录
    KATArray<KATHashMap *> *daysLogs=[router.historyLogs allValues];
    
    if(daysLogs && daysLogs.length>0)
    {
        //从后往前遍历
        for(int i=daysLogs.length-1;i>=0;i--)
        {
            KATHashMap *dayLogs=daysLogs[i];
            
            //当日的日志
            KATArray<KATHashMap *> *logs=dayLogs[kRouterLogsKeyLogs];
            
            if(logs && logs.length>0)
            {
                //从后往前遍历
                for(int j=logs.length-1;j>=0;j--)
                {
                    KATHashMap *log=logs[j];
                    
                    KATArray<KATHashMap *> *hostsLog=log[kRouterLogsKeyHosts];
                    
                    if(hostsLog && hostsLog.length>0)
                    {
                        //从后往前遍历
                        for(int k=hostsLog.length-1;k>=0;k--)
                        {
                            KATHashMap *hostLog=hostsLog[k];
                            
                            if([host isEqualToString:hostLog[kRouterLogsKeyHost]])
                            {
                                if(hostLog!=router.hostLog)//非本次host记录
                                {
                                    int lastDay=(int)([hostLog[kRouterLogsKeyHostLeaveTime] longLongValue]/1000000);
                                    
                                    return [KATDateUtil daysPastFrom:lastDay to:[KATDateUtil today]];
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    
    return -1;
}


//获取最近一次事件(内部方法)
+ (KATHashMap *)_lastEvent:(NSString *)event
{
    if(!event)
    {
        return nil;
    }
    
    KATRouter *router=[self sharedRouter];
    
    //获取历史记录
    KATArray<KATHashMap *> *daysLogs=[router.historyLogs allValues];
    
    if(daysLogs && daysLogs.length>0)
    {
        //从后往前遍历
        for(int i=daysLogs.length-1;i>=0;i--)
        {
            KATHashMap *dayLogs=daysLogs[i];
            
            //当日的日志
            KATArray<KATHashMap *> *logs=dayLogs[kRouterLogsKeyLogs];
            
            if(logs && logs.length>0)
            {
                //从后往前遍历
                for(int j=logs.length-1;j>=0;j--)
                {
                    KATHashMap *log=logs[j];
                    
                    KATArray<KATHashMap *> *hostsLog=log[kRouterLogsKeyHosts];
                    
                    if(hostsLog && hostsLog.length>0)
                    {
                        //从后往前遍历
                        for(int k=hostsLog.length-1;k>=0;k--)
                        {
                            KATHashMap *hostLog=hostsLog[k];
                            
                            KATArray<KATHashMap *> *eventsLog=hostLog[kRouterLogsKeyEvents];
                            
                            if(eventsLog && eventsLog.length>0)
                            {
                                //从后往前遍历
                                for(int x=eventsLog.length-1;x>=0;x--)
                                {
                                    KATHashMap *eventLog=eventsLog[x];
                                    
                                    if([event isEqualToString:eventLog[kRouterLogsKeyEvent]])
                                    {
                                        KATHashMap *result=[eventLog copy];
                                        result[kRouterLogsKeyID]=log[kRouterLogsKeyID];
                                        result[kRouterLogsKeyDate]=log[kRouterLogsKeyDate];
                                        result[kRouterLogsKeyHost]=hostLog[kRouterLogsKeyHost];
                                        
                                        return result;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    
    return nil;
}


//获取最近一次事件到现在的天数(没有则返回负数)
+ (int)daysFromLastEvent:(NSString *)event
{
    KATHashMap *eventLog=[self _lastEvent:event];
    
    if(event && eventLog)
    {
        int lastDay=(int)([eventLog[kRouterLogsKeyEventTime] longLongValue]/1000000000);
        
        return [KATDateUtil daysPastFrom:lastDay to:[KATDateUtil today]];
    }
    
    return -1;
}


//获取该host当日的使用秒数
+ (long long)secondsByDayUsingWithHost:(NSString *)host
{
    if(!host)
    {
        return -1;
    }
    
    KATRouter *router=[self sharedRouter];
    
    //当日的日志
    KATArray<KATHashMap *> *logs=router.dayLogs[kRouterLogsKeyLogs];
    
    if(logs && logs.length>0)
    {
        long long seconds=0;
        
        //从后往前遍历
        for(int j=logs.length-1;j>=0;j--)
        {
            KATHashMap *log=logs[j];
            
            KATArray<KATHashMap *> *hostsLog=log[kRouterLogsKeyHosts];
            
            if(hostsLog && hostsLog.length>0)
            {
                //从后往前遍历
                for(int k=hostsLog.length-1;k>=0;k--)
                {
                    KATHashMap *hostLog=hostsLog[k];
                    
                    if([host isEqualToString:hostLog[kRouterLogsKeyHost]])
                    {
                        seconds+=[hostLog[kRouterLogsKeyHostDuration] longLongValue];
                    }
                }
            }
        }
        
        if([host isEqualToString:[KATRouter currentHost]])//如果当前正在使用，补上
        {
            seconds+=[KATRouter durationByHostUsing];
        }
        
        return seconds;
    }
    
    return -1;
}



//获取该host数组当日的使用秒数
+ (long long)secondsByDayUsingWithHosts:(KATArray<NSString *> *)hosts
{
    if(!hosts || hosts.length<0)
    {
        return -1;
    }
    
    long long seconds=0;
    
    //遍历数组
    for(NSString *host in hosts)
    {
        long long s=[KATRouter secondsByDayUsingWithHost:host];
        
        if(s>0)
        {
            seconds+=s;
        }
    }
    
    return seconds;
}


//获取该host在本次app使用中的使用秒数
+ (long long)secondsByAppUsingWithHost:(NSString *)host
{
    if(!host)
    {
        return -1;
    }
    
    KATRouter *router=[self sharedRouter];
    
    KATArray<KATHashMap *> *hostsLog=router.appLog[kRouterLogsKeyHosts];
    
    if(hostsLog && hostsLog.length>0)
    {
        long long seconds=0;
        
        //从后往前遍历
        for(int k=hostsLog.length-1;k>=0;k--)
        {
            KATHashMap *hostLog=hostsLog[k];
            
            if([host isEqualToString:hostLog[kRouterLogsKeyHost]])
            {
                seconds+=[hostLog[kRouterLogsKeyHostDuration] longLongValue];
            }
        }
        
        if([host isEqualToString:[KATRouter currentHost]])//如果当前正在使用，补上
        {
            seconds+=[KATRouter durationByHostUsing];
        }
        
        return seconds;
    }
    
    return -1;
}


//获取该host数组在本次app使用中的使用秒数
+ (long long)secondsByAppUsingWithHosts:(KATArray<NSString *> *)hosts
{
    if(!hosts || hosts.length<0)
    {
        return -1;
    }
    
    long long seconds=0;
    
    //遍历数组
    for(NSString *host in hosts)
    {
        long long s=[KATRouter secondsByAppUsingWithHost:host];
        
        if(s>0)
        {
            seconds+=s;
        }
    }
    
    return seconds;
}


//获取最近一次事件到现在的秒数(没有则返回负数)
+ (long long)secondsFromLastEvent:(NSString *)event
{
    KATHashMap *eventLog=[self _lastEvent:event];
    
    if(event && eventLog)
    {
        long long lastTime=[eventLog[kRouterLogsKeyEventTime] longLongValue]*10;
        
        return [KATDateUtil difSecondsFromTime:lastTime toTime:[KATDateUtil now]];
    }
    
    return -1;
}


//获取当日最近一次事件到现在的秒数(没有则返回负数)
+ (long long)secondsByDayUsingFromLastEvent:(NSString *)event
{
    KATRouter *router=[self sharedRouter];
    
    //当日的日志
    KATArray<KATHashMap *> *logs=router.dayLogs[kRouterLogsKeyLogs];
    
    if(event && logs && logs.length>0)
    {
        //从后往前遍历
        for(int j=logs.length-1;j>=0;j--)
        {
            KATHashMap *log=logs[j];
            
            KATArray<KATHashMap *> *hostsLog=log[kRouterLogsKeyHosts];
            
            if(hostsLog && hostsLog.length>0)
            {
                //从后往前遍历
                for(int k=hostsLog.length-1;k>=0;k--)
                {
                    KATHashMap *hostLog=hostsLog[k];
                    
                    KATArray<KATHashMap *> *eventsLog=hostLog[kRouterLogsKeyEvents];
                    
                    if(eventsLog && eventsLog.length>0)
                    {
                        //从后往前遍历
                        for(int x=eventsLog.length-1;x>=0;x--)
                        {
                            KATHashMap *eventLog=eventsLog[x];
                            
                            if([event isEqualToString:eventLog[kRouterLogsKeyEvent]])
                            {
                                int date=(int)([eventLog[kRouterLogsKeyEventTime] longLongValue]/1000000000);
                                
                                if(date>=[KATDateUtil today])//当日
                                {
                                    long long lastTime=[eventLog[kRouterLogsKeyEventTime] longLongValue]*10;
                                    
                                    return [KATDateUtil difSecondsFromTime:lastTime toTime:[KATDateUtil now]];
                                }
                                else//非当日
                                {
                                    return -1;
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    
    return -1;
}


//获取本次app使用中最近一次事件到现在的秒数(没有则返回负数)
+ (long long)secondsByAppUsingFromLastEvent:(NSString *)event
{
    KATRouter *router=[self sharedRouter];
    
    KATArray<KATHashMap *> *hostsLog=router.appLog[kRouterLogsKeyHosts];
    
    if(event && hostsLog && hostsLog.length>0)
    {
        //从后往前遍历
        for(int k=hostsLog.length-1;k>=0;k--)
        {
            KATHashMap *hostLog=hostsLog[k];
            
            KATArray<KATHashMap *> *eventsLog=hostLog[kRouterLogsKeyEvents];
            
            if(eventsLog && eventsLog.length>0)
            {
                //从后往前遍历
                for(int x=eventsLog.length-1;x>=0;x--)
                {
                    KATHashMap *eventLog=eventsLog[x];
                    
                    if([event isEqualToString:eventLog[kRouterLogsKeyEvent]])
                    {
                        long long lastTime=[eventLog[kRouterLogsKeyEventTime] longLongValue]*10;
                        
                        return [KATDateUtil difSecondsFromTime:lastTime toTime:[KATDateUtil now]];
                    }
                }
            }
        }
    }
    
    return -1;
}


//获取当前host中最近一次事件到现在的秒数(没有则返回负数)
+ (long long)secondsByHostUsingFromLastEvent:(NSString *)event
{
    KATRouter *router=[self sharedRouter];
    
    KATArray<KATHashMap *> *eventsLog=router.hostLog[kRouterLogsKeyEvents];
    
    if(event && eventsLog && eventsLog.length>0)
    {
        //从后往前遍历
        for(int x=eventsLog.length-1;x>=0;x--)
        {
            KATHashMap *eventLog=eventsLog[x];
            
            if([event isEqualToString:eventLog[kRouterLogsKeyEvent]])
            {
                long long lastTime=[eventLog[kRouterLogsKeyEventTime] longLongValue]*10;
                
                return [KATDateUtil difSecondsFromTime:lastTime toTime:[KATDateUtil now]];
            }
        }
    }
    
    return -1;
}


//历史上触发该事件的总次数
+ (int)countInHistoryWithEvent:(NSString *)event
{
    KATRouter *router=[self sharedRouter];
    
    return [self countInDays:router.logsKeepingDays withEvent:event];
}


//历史上触发该事件数组的总次数
+ (int)countInHistoryWithEvents:(KATArray<NSString *> *)events
{
    if(events && events.length>0)
    {
        int count=0;
        
        for(NSString *event in events)
        {
            int c=[KATRouter countInHistoryWithEvent:event];
            
            if(c>0)
            {
                count+=c;
            }
        }
        
        return count;
    }
    
    return -1;
}


//当日触发该事件的次数
+ (int)countInDayUsingWithEvent:(NSString *)event
{
    return [self countInDays:0 withEvent:event];
}


//当日触发该事件数组的总次数
+ (int)countInDayUsingWithEvents:(KATArray<NSString *> *)events
{
    if(events && events.length>0)
    {
        int count=0;
        
        for(NSString *event in events)
        {
            int c=[KATRouter countInDayUsingWithEvent:event];
            
            if(c>0)
            {
                count+=c;
            }
        }
        
        return count;
    }
    
    return -1;
}


//多少日内触发该事件的次数
+ (int)countInDays:(int)days withEvent:(NSString *)event
{
    if(event && days>=0 && event)
    {
        KATRouter *router=[self sharedRouter];
        
        int count=0;
        
        //开始日期
        int beginDay=[KATDateUtil theDayBefore:days onDay:[KATDateUtil today]];
        
        //日期日志数组
        KATArray<KATHashMap *> *daysLogs=[router.historyLogs valuesFromKey:[NSString stringWithFormat:@"%i",beginDay]];
        
        if(daysLogs && daysLogs.length>0)
        {
            //从后往前遍历
            for(int i=daysLogs.length-1;i>=0;i--)
            {
                KATHashMap *dayLogs=daysLogs[i];
                
                //当日的日志
                KATArray<KATHashMap *> *logs=dayLogs[kRouterLogsKeyLogs];
                
                if(logs && logs.length>0)
                {
                    //从后往前遍历
                    for(int j=logs.length-1;j>=0;j--)
                    {
                        KATHashMap *log=logs[j];
                        
                        KATArray<KATHashMap *> *hostsLog=log[kRouterLogsKeyHosts];
                        
                        if(hostsLog && hostsLog.length>0)
                        {
                            //从后往前遍历
                            for(int k=hostsLog.length-1;k>=0;k--)
                            {
                                KATHashMap *hostLog=hostsLog[k];
                                
                                KATArray<KATHashMap *> *eventsLog=hostLog[kRouterLogsKeyEvents];
                                
                                if(eventsLog && eventsLog.length>0)
                                {
                                    //从后往前遍历
                                    for(int x=eventsLog.length-1;x>=0;x--)
                                    {
                                        KATHashMap *eventLog=eventsLog[x];
                                        
                                        if([event isEqualToString:eventLog[kRouterLogsKeyEvent]])
                                        {
                                            count++;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        
        return count;
    }
    
    return -1;
}


//多少日内触发该事件数组的总次数(0代表当天，1代表当天和昨天)
+ (int)countInDays:(int)days withEvents:(KATArray<NSString *> *)events
{
    if(events && events.length>0)
    {
        int count=0;
        
        for(NSString *event in events)
        {
            int c=[KATRouter countInDays:days withEvent:event];
            
            if(c>0)
            {
                count+=c;
            }
        }
        
        return count;
    }
    
    return -1;
}


//本次app使用中触发该事件的次数
+ (int)countInAppUsingWithEvent:(NSString *)event
{
    KATRouter *router=[self sharedRouter];
    
    int count=0;
    
    KATArray<KATHashMap *> *hostsLog=router.appLog[kRouterLogsKeyHosts];
    
    if(event && hostsLog && hostsLog.length>0)
    {
        //从后往前遍历
        for(int k=hostsLog.length-1;k>=0;k--)
        {
            KATHashMap *hostLog=hostsLog[k];
            
            KATArray<KATHashMap *> *eventsLog=hostLog[kRouterLogsKeyEvents];
            
            if(eventsLog && eventsLog.length>0)
            {
                //从后往前遍历
                for(int x=eventsLog.length-1;x>=0;x--)
                {
                    KATHashMap *eventLog=eventsLog[x];
                    
                    if([event isEqualToString:eventLog[kRouterLogsKeyEvent]])
                    {
                        count++;
                    }
                }
            }
        }
    }
    
    return count;
}


//获取最近一次事件
+ (KATHashMap *)getLastEvent:(NSString *)event
{
    return [KATRouter _lastEvent:event];
}


//获取指定ID的事件(IDs为空时返回所有的)
+ (KATArray<KATHashMap *> *)eventsWithIDs:(KATArray<NSString *> *)IDs
{
    KATArray<KATHashMap *> *events=[KATArray array];
    
    KATRouter *router=[self sharedRouter];
    
    //获取历史记录
    KATArray<KATHashMap *> *daysLogs=[router.historyLogs allValues];
    
    if(daysLogs && daysLogs.length>0)
    {
        //从后往前遍历
        for(int i=daysLogs.length-1;i>=0;i--)
        {
            KATHashMap *dayLogs=daysLogs[i];
            
            //当日的日志
            KATArray<KATHashMap *> *logs=dayLogs[kRouterLogsKeyLogs];
            
            if(logs && logs.length>0)
            {
                //从后往前遍历
                for(int j=logs.length-1;j>=0;j--)
                {
                    KATHashMap *log=logs[j];
                    
                    KATArray<KATHashMap *> *hostsLog=log[kRouterLogsKeyHosts];
                    
                    if(hostsLog && hostsLog.length>0)
                    {
                        //从后往前遍历
                        for(int k=hostsLog.length-1;k>=0;k--)
                        {
                            KATHashMap *hostLog=hostsLog[k];
                            
                            KATArray<KATHashMap *> *eventsLog=hostLog[kRouterLogsKeyEvents];
                            
                            if(eventsLog && eventsLog.length>0)
                            {
                                //从后往前遍历
                                for(int x=eventsLog.length-1;x>=0;x--)
                                {
                                    KATHashMap *eventLog=eventsLog[x];
                                    
                                    //用户过滤
                                    if(IDs && IDs.length>0)
                                    {
                                        if(log[kRouterLogsKeyID] && [IDs hasMember:log[kRouterLogsKeyID]])
                                        {
                                            //找到
                                        }
                                        else
                                        {
                                            continue;
                                        }
                                    }
                                    
                                    KATHashMap *event=[eventLog copy];
                                    event[kRouterLogsKeyID]=log[kRouterLogsKeyID];
                                    event[kRouterLogsKeyDate]=log[kRouterLogsKeyDate];
                                    event[kRouterLogsKeyHost]=hostLog[kRouterLogsKeyHost];
                                    
                                    [events put:event];
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    
    return events;
}


//本次app使用中触发该事件数组的总次数
+ (int)countInAppUsingWithEvents:(KATArray<NSString *> *)events
{
    if(events && events.length>0)
    {
        int count=0;
        
        for(NSString *event in events)
        {
            int c=[KATRouter countInAppUsingWithEvent:event];
            
            if(c>0)
            {
                count+=c;
            }
        }
        
        return count;
    }
    
    return -1;
}


//在当前host中触发该事件的次数
+ (int)countInHostUsingWithEvent:(NSString *)event
{
    KATRouter *router=[self sharedRouter];
    
    int count=0;
    
    KATArray<KATHashMap *> *eventsLog=router.hostLog[kRouterLogsKeyEvents];
    
    if(event && eventsLog && eventsLog.length>0)
    {
        //从后往前遍历
        for(int x=eventsLog.length-1;x>=0;x--)
        {
            KATHashMap *eventLog=eventsLog[x];
            
            if([event isEqualToString:eventLog[kRouterLogsKeyEvent]])
            {
                count++;
            }
        }
    }
    
    return count;
}


//在当前host中触发该事件数组的总次数
+ (int)countInHostUsingWithEvents:(KATArray<NSString *> *)events
{
    if(events && events.length>0)
    {
        int count=0;
        
        for(NSString *event in events)
        {
            int c=[KATRouter countInHostUsingWithEvent:event];
            
            if(c>0)
            {
                count+=c;
            }
        }
        
        return count;
    }
    
    return -1;
}


#pragma -mark 任务(在主线程中执行)(可以删除后再添加，但不能覆盖)


//加载任务文件(内部方法)
- (void)loadMissions
{
    KATHashMap *missions=nil;
    
    self.daysMissions=[KATHashMap hashMap];
    
    missions=[KATHashMap hashMapWithFile:[NSString stringWithFormat:@"%@/%@",_logsDir,kRouterDaysMissions]];
    
    if(missions)
    {
        KATArray *missionArray=[missions allValues];
        
        for(KATHashMap *map in missionArray)
        {
            KATRouterMission *mission=[map object];
            
            _daysMissions[mission.name]=mission;
        }
    }
    
    self.durationMissions=[KATHashMap hashMap];
    
    missions=[KATHashMap hashMapWithFile:[NSString stringWithFormat:@"%@/%@",_logsDir,kRouterDurationMissions]];
    
    if(missions)
    {
        KATArray *missionArray=[missions allValues];
        
        for(KATHashMap *map in missionArray)
        {
            KATRouterMission *mission=[map object];
            
            _durationMissions[mission.name]=mission;
        }
    }
    
    self.countMissions=[KATHashMap hashMap];
    
    missions=[KATHashMap hashMapWithFile:[NSString stringWithFormat:@"%@/%@",_logsDir,kRouterCountMissions]];
    
    if(missions)
    {
        KATArray *missionArray=[missions allValues];
        
        for(KATHashMap *map in missionArray)
        {
            KATRouterMission *mission=[map object];
            
            _countMissions[mission.name]=mission;
        }
    }
    
    //启动定时器
    [self startDurationMissionTimer];
}


//保存任务文件(内部方法)
- (void)saveMissions
{
    [_daysMissions saveToFile:[NSString stringWithFormat:@"%@/%@",_logsDir,kRouterDaysMissions]];
    [_durationMissions saveToFile:[NSString stringWithFormat:@"%@/%@",_logsDir,kRouterDurationMissions]];
    [_countMissions saveToFile:[NSString stringWithFormat:@"%@/%@",_logsDir,kRouterCountMissions]];
}




//添加未使用app的天数触发的任务(超过天数则触发)(app打开时判断执行)
+ (void)addMission:(NSString *)mission forUnusedDays:(unsigned int)days withObserver:(NSString *)observerHost selector:(NSString *)selector andTimes:(unsigned int)times
{
    KATRouter *router=[self sharedRouter];
    
    if(!router.daysMissions)
    {
        [router loadMissions];
    }
    
    if(mission && observerHost && selector)
    {
        if([KATRouter hasMission:mission])
        {
            return;
        }
        
        //创建日志动作
        KATRouterMission *mis=[KATRouterMission mission];
        mis.name=mission;
        mis.type=ROUTER_MISSION_TYPE_APP_USING;
        mis.days=days;
        mis.observer=observerHost;
        mis.sel=selector;
        mis.times=times;
        
        router.daysMissions[mission]=mis;
        
        //覆盖其他两个map
        router.durationMissions[mission]=nil;
        router.countMissions[mission]=nil;
    }
}


//添加未使用host的天数触发的任务(超过天数则触发)(app打开时判断执行)
+ (void)addMission:(NSString *)mission withHost:(NSString *)host forUnusedDays:(unsigned int)days observer:(NSString *)observerHost selector:(NSString *)selector andTimes:(unsigned int)times
{
    KATRouter *router=[self sharedRouter];
    
    if(!router.daysMissions)
    {
        [router loadMissions];
    }
    
    if(mission && host && observerHost && selector)
    {
        if([KATRouter hasMission:mission])
        {
            return;
        }
        
        //创建日志动作
        KATRouterMission *mis=[KATRouterMission mission];
        mis.name=mission;
        mis.type=ROUTER_MISSION_TYPE_HOST_USING;
        mis.host=host;
        mis.days=days;
        mis.observer=observerHost;
        mis.sel=selector;
        mis.times=times;
        
        router.daysMissions[mission]=mis;
        
        //覆盖其他两个map
        router.durationMissions[mission]=nil;
        router.countMissions[mission]=nil;
    }
}


//添加未触发事件的天数触发的任务(超过天数则触发)(app打开时判断执行)
+ (void)addMission:(NSString *)mission withEvent:(NSString *)event forUntriggeredDays:(unsigned int)days observer:(NSString *)observerHost selector:(NSString *)selector andTimes:(unsigned int)times
{
    KATRouter *router=[self sharedRouter];
    
    if(!router.daysMissions)
    {
        [router loadMissions];
    }
    
    if(mission && event && observerHost && selector)
    {
        if([KATRouter hasMission:mission])
        {
            return;
        }
        
        //创建日志动作
        KATRouterMission *mis=[KATRouterMission mission];
        mis.name=mission;
        mis.type=ROUTER_MISSION_TYPE_EVENT;
        mis.event=event;
        mis.days=days;
        mis.observer=observerHost;
        mis.sel=selector;
        mis.times=times;
        
        router.daysMissions[mission]=mis;
        
        //覆盖其他两个map
        router.durationMissions[mission]=nil;
        router.countMissions[mission]=nil;
    }
}


//执行天数类型的任务(内部方法)
- (void)executeDaysMissions
{
    if(!_daysMissions)
    {
        [self loadMissions];
    }
    
    KATArray<KATRouterMission *> *missions=[_daysMissions allValues];
    
    //遍历执行
    for(KATRouterMission *mission in missions)
    {
        BOOL needRemove=NO;
        BOOL execution=NO;
        
        //不存在该host则释放
        if(!mission.observer || !_classMap[mission.observer])
        {
            needRemove=YES;
        }
        
        if(mission.type==ROUTER_MISSION_TYPE_APP_USING)//app使用
        {
            int days=[KATRouter daysFromLastLog];//未使用app的天数
            
            if(days>=0 && days>=mission.days)
            {
                execution=YES;
            }
        }
        else if(mission.type==ROUTER_MISSION_TYPE_HOST_USING)//host使用
        {
            if(mission.host)
            {
                int days=[KATRouter daysFromLastUsingWithHost:mission.host];
                
                if(days<0)//没有使用过host，则计算最早日志时间
                {
                    days=[KATRouter daysFromFirstLog];
                }
                
                if(days>=0 && days>=mission.days)
                {
                    execution=YES;
                }
            }
            else
            {
                needRemove=YES;
            }
        }
        else if(mission.type==ROUTER_MISSION_TYPE_EVENT)//事件
        {
            if(mission.event)
            {
                int days=[KATRouter daysFromLastEvent:mission.event];
                
                if(days>=0 && days>=mission.days)
                {
                    execution=YES;
                }
            }
            else
            {
                needRemove=YES;
            }
        }
        
        if(execution)//执行
        {
            //执行次数减少一次
            mission.times--;
            
            //执行次数少于1则释放
            if(mission.times<=0)
            {
                //先删除后执行
                [KATRouter removeMission:mission.name];
            }
            
            if(mission.observer && mission.sel && _classMap[mission.observer])
            {
                UIViewController *vc=_instanceMap[mission.observer];//获取实例
                
                if(!vc || ![vc isKindOfClass:[UIViewController class]])//不存在或者被释放则创建
                {
                    Class cls=NSClassFromString(_classMap[mission.observer]);
                    
                    if(cls)
                    {
                        vc=[[[cls alloc] init] autorelease];
                        
                        //关联host
                        objc_setAssociatedObject(vc, kRouterKeyHost, mission.observer, OBJC_ASSOCIATION_COPY_NONATOMIC);
                        
                        _instanceMap[mission.observer]=vc;
                        
                        //挂钩支持屏幕方向
                        [KATRouter hookSupportedOrientationsWithVC:vc];
                        
                        //值容器表
                        if(!_valueMap[mission.observer])
                        {
                            _valueMap[mission.observer]=[KATHashMap hashMap];
                        }
                    }
                    else
                    {
                        vc=nil;
                    }
                }
                
                SEL selector=NSSelectorFromString(mission.sel);
                
                if(vc && [vc respondsToSelector:selector])
                {
                    [vc performSelectorOnMainThread:selector withObject:nil waitUntilDone:NO];
                }
            }
        }
        else
        {
            //释放
            if(needRemove)
            {
                [KATRouter removeMission:mission.name];
            }
        }
    }
}


//添加当日使用时长任务(超过时长则触发，只触发一次)
+ (void)addMission:(NSString *)mission byDayUsingForDuration:(unsigned int)seconds withObserver:(NSString *)observerHost andSelector:(NSString *)selector
{
    KATRouter *router=[self sharedRouter];
    
    if(!router.durationMissions)
    {
        [router loadMissions];
    }
    
    if(mission && observerHost && selector)
    {
        if([KATRouter hasMission:mission])
        {
            return;
        }
        
        //创建日志动作
        KATRouterMission *mis=[KATRouterMission mission];
        mis.name=mission;
        mis.type=ROUTER_MISSION_TYPE_DAY_USING;
        mis.duration=seconds;
        mis.observer=observerHost;
        mis.sel=selector;
        mis.times=1;
        
        router.durationMissions[mission]=mis;
        
        //覆盖其他两个map
        router.countMissions[mission]=nil;
        router.daysMissions[mission]=nil;
        
        //启动定时器
        [router startDurationMissionTimer];
    }
}


//添加app使用时长任务(超过时长则触发，只触发一次)
+ (void)addMission:(NSString *)mission byAppUsingForDuration:(unsigned int)seconds withObserver:(NSString *)observerHost andSelector:(NSString *)selector
{
    KATRouter *router=[self sharedRouter];
    
    if(!router.durationMissions)
    {
        [router loadMissions];
    }
    
    if(mission && observerHost && selector)
    {
        if([KATRouter hasMission:mission])
        {
            return;
        }
        
        //创建日志动作
        KATRouterMission *mis=[KATRouterMission mission];
        mis.name=mission;
        mis.type=ROUTER_MISSION_TYPE_APP_USING;
        mis.duration=seconds;
        mis.observer=observerHost;
        mis.sel=selector;
        mis.times=1;
        
        router.durationMissions[mission]=mis;
        
        //覆盖其他两个map
        router.countMissions[mission]=nil;
        router.daysMissions[mission]=nil;
        
        //启动定时器
        [router startDurationMissionTimer];
    }
}


//添加host停留时长任务(超过时长则触发，只触发一次)
+ (void)addMission:(NSString *)mission byUsingHost:(NSString *)host forDuration:(unsigned int)seconds observer:(NSString *)observerHost andSelector:(NSString *)selector
{
    KATRouter *router=[self sharedRouter];
    
    if(!router.durationMissions)
    {
        [router loadMissions];
    }
    
    if(mission && host && observerHost && selector)
    {
        if([KATRouter hasMission:mission])
        {
            return;
        }
        
        //创建日志动作
        KATRouterMission *mis=[KATRouterMission mission];
        mis.name=mission;
        mis.type=ROUTER_MISSION_TYPE_HOST_USING;
        mis.duration=seconds;
        mis.observer=observerHost;
        mis.sel=selector;
        mis.host=host;
        mis.times=1;
        
        router.durationMissions[mission]=mis;
        
        //覆盖其他两个map
        router.countMissions[mission]=nil;
        router.daysMissions[mission]=nil;
        
        //启动定时器
        [router startDurationMissionTimer];
    }
}


//添加app使用中host停留时长任务(超过时长则触发，只触发一次)
+ (void)addMission:(NSString *)mission byAppUsingWithHost:(NSString *)host forDuration:(unsigned int)seconds observer:(NSString *)observerHost andSelector:(NSString *)selector
{
    KATRouter *router=[self sharedRouter];
    
    if(!router.durationMissions)
    {
        [router loadMissions];
    }
    
    if(mission && host && observerHost && selector)
    {
        if([KATRouter hasMission:mission])
        {
            return;
        }
        
        //创建日志动作
        KATRouterMission *mis=[KATRouterMission mission];
        mis.name=mission;
        mis.type=ROUTER_MISSION_TYPE_HOST_APP_USING;
        mis.duration=seconds;
        mis.observer=observerHost;
        mis.sel=selector;
        mis.host=host;
        mis.times=1;
        
        router.durationMissions[mission]=mis;
        
        //覆盖其他两个map
        router.countMissions[mission]=nil;
        router.daysMissions[mission]=nil;
        
        //启动定时器
        [router startDurationMissionTimer];
    }
}


//添加app使用中host数组总停留时长任务(超过时长则触发，只触发一次)
+ (void)addMission:(NSString *)mission byAppUsingWithHosts:(KATArray<NSString *> *)hosts forDuration:(unsigned int)seconds observer:(NSString *)observerHost andSelector:(NSString *)selector
{
    KATRouter *router=[self sharedRouter];
    
    if(!router.durationMissions)
    {
        [router loadMissions];
    }
    
    if(mission && hosts && hosts.length>0 && observerHost && selector)
    {
        if([KATRouter hasMission:mission])
        {
            return;
        }
        
        //创建日志动作
        KATRouterMission *mis=[KATRouterMission mission];
        mis.name=mission;
        mis.type=ROUTER_MISSION_TYPE_HOSTS_APP_USING;
        mis.duration=seconds;
        mis.observer=observerHost;
        mis.sel=selector;
        mis.hosts=hosts;
        mis.times=1;
        
        router.durationMissions[mission]=mis;
        
        //覆盖其他两个map
        router.countMissions[mission]=nil;
        router.daysMissions[mission]=nil;
        
        //启动定时器
        [router startDurationMissionTimer];
    }
}


//添加当日host停留时长任务(超过时长则触发，只触发一次)
+ (void)addMission:(NSString *)mission byDayUsingWithHost:(NSString *)host forDuration:(unsigned int)seconds observer:(NSString *)observerHost andSelector:(NSString *)selector
{
    KATRouter *router=[self sharedRouter];
    
    if(!router.durationMissions)
    {
        [router loadMissions];
    }
    
    if(mission && host && observerHost && selector)
    {
        if([KATRouter hasMission:mission])
        {
            return;
        }
        
        //创建日志动作
        KATRouterMission *mis=[KATRouterMission mission];
        mis.name=mission;
        mis.type=ROUTER_MISSION_TYPE_HOST_DAY_USING;
        mis.duration=seconds;
        mis.observer=observerHost;
        mis.sel=selector;
        mis.host=host;
        mis.times=1;
        
        router.durationMissions[mission]=mis;
        
        //覆盖其他两个map
        router.countMissions[mission]=nil;
        router.daysMissions[mission]=nil;
        
        //启动定时器
        [router startDurationMissionTimer];
    }
}


//添加当日host数组总停留时长任务(超过时长则触发，只触发一次)
+ (void)addMission:(NSString *)mission byDayUsingWithHosts:(KATArray<NSString *> *)hosts forDuration:(unsigned int)seconds observer:(NSString *)observerHost andSelector:(NSString *)selector
{
    KATRouter *router=[self sharedRouter];
    
    if(!router.durationMissions)
    {
        [router loadMissions];
    }
    
    if(mission && hosts && hosts.length>0 && observerHost && selector)
    {
        if([KATRouter hasMission:mission])
        {
            return;
        }
        
        //创建日志动作
        KATRouterMission *mis=[KATRouterMission mission];
        mis.name=mission;
        mis.type=ROUTER_MISSION_TYPE_HOSTS_DAY_USING;
        mis.duration=seconds;
        mis.observer=observerHost;
        mis.sel=selector;
        mis.hosts=hosts;
        mis.times=1;
        
        router.durationMissions[mission]=mis;
        
        //覆盖其他两个map
        router.countMissions[mission]=nil;
        router.daysMissions[mission]=nil;
        
        //启动定时器
        [router startDurationMissionTimer];
    }
}


//添加当日未触发事件时长的任务(超过时长则触发，只触发一次)
+ (void)addMission:(NSString *)mission withEvent:(NSString *)event forUntriggeredDuration:(unsigned int)seconds observer:(NSString *)observerHost andSelector:(NSString *)selector
{
    KATRouter *router=[self sharedRouter];
    
    if(!router.durationMissions)
    {
        [router loadMissions];
    }
    
    if(mission && event && observerHost && selector)
    {
        if([KATRouter hasMission:mission])
        {
            return;
        }
        
        //创建日志动作
        KATRouterMission *mis=[KATRouterMission mission];
        mis.name=mission;
        mis.type=ROUTER_MISSION_TYPE_EVENT;
        mis.duration=seconds;
        mis.observer=observerHost;
        mis.sel=selector;
        mis.event=event;
        mis.times=1;
        
        router.durationMissions[mission]=mis;
        
        //覆盖其他两个map
        router.countMissions[mission]=nil;
        router.daysMissions[mission]=nil;
        
        //启动定时器
        [router startDurationMissionTimer];
    }
}


//添加定时任务(超过时长则触发，只触发一次)
+ (void)addMission:(NSString *)mission forDuration:(unsigned int)seconds withObserver:(NSString *)observerHost andSelector:(NSString *)selector
{
    KATRouter *router=[self sharedRouter];
    
    if(!router.durationMissions)
    {
        [router loadMissions];
    }
    
    if(mission && observerHost && selector)
    {
        if([KATRouter hasMission:mission])
        {
            return;
        }
        
        //创建日志动作
        KATRouterMission *mis=[KATRouterMission mission];
        mis.name=mission;
        mis.type=ROUTER_MISSION_TYPE_NONE;
        mis.duration=seconds;
        mis.observer=observerHost;
        mis.sel=selector;
        mis.times=1;
        
        router.durationMissions[mission]=mis;
        
        //覆盖其他两个map
        router.countMissions[mission]=nil;
        router.daysMissions[mission]=nil;
        
        //启动定时器
        [router startDurationMissionTimer];
    }
}


//执行持续时长类型的任务(内部方法)
- (void)executeDurationMissions
{
    //先执行定时器动作
    if(_timerAction)
    {
        _timerAction();
    }
    
    //加载任务
    if(!_durationMissions)
    {
        [self loadMissions];
    }
    
    dispatch_async(_queueDurationMissions, ^
    {
        KATArray<KATRouterMission *> *missions=[_durationMissions allValues];
        
        //遍历执行
        for(KATRouterMission *mission in missions)
        {
            BOOL needRemove=NO;
            long long seconds=-1;
            
            //不存在该host则释放
            if(!mission.observer || !_classMap[mission.observer])
            {
                needRemove=YES;
            }
            
            if(mission.type==ROUTER_MISSION_TYPE_DAY_USING)//当日使用时长
            {
                seconds=[KATRouter durationByDayUsing];
            }
            if(mission.type==ROUTER_MISSION_TYPE_APP_USING)//app使用时长
            {
                seconds=[KATRouter durationByAppUsing];
            }
            else if(mission.type==ROUTER_MISSION_TYPE_HOST_USING)//host使用时长
            {
                if(mission.host)
                {
                    if([mission.host isEqualToString:[KATRouter currentHost]])
                    {
                        seconds=[KATRouter durationByHostUsing];
                    }
                }
                else
                {
                    needRemove=YES;
                }
            }
            else if(mission.type==ROUTER_MISSION_TYPE_HOST_APP_USING)//host本次app中的使用时长
            {
                if(mission.host)
                {
                    seconds=[KATRouter secondsByAppUsingWithHost:mission.host];
                }
                else
                {
                    needRemove=YES;
                }
            }
            else if(mission.type==ROUTER_MISSION_TYPE_HOST_DAY_USING)//host当日使用时长
            {
                if(mission.host)
                {
                    seconds=[KATRouter secondsByDayUsingWithHost:mission.host];
                }
                else
                {
                    needRemove=YES;
                }
            }
            else if(mission.type==ROUTER_MISSION_TYPE_HOSTS_APP_USING)//host数组本次app中的使用总时长
            {
                if(mission.hosts && mission.hosts.length>0)
                {
                    seconds=[KATRouter secondsByAppUsingWithHosts:mission.hosts];
                }
                else
                {
                    needRemove=YES;
                }
            }
            else if(mission.type==ROUTER_MISSION_TYPE_HOSTS_DAY_USING)//host数组当日的使用总时长
            {
                if(mission.hosts && mission.hosts.length>0)
                {
                    seconds=[KATRouter secondsByDayUsingWithHosts:mission.hosts];
                }
                else
                {
                    needRemove=YES;
                }
            }
            else if(mission.type==ROUTER_MISSION_TYPE_EVENT)//事件未触发时长
            {
                if(mission.event)
                {
                    seconds=[KATRouter secondsByDayUsingFromLastEvent:mission.event];
                    
                    if(seconds<0)//未触发，则用当日使用时长
                    {
                        seconds=[KATRouter durationByDayUsing];
                    }
                }
                else
                {
                    needRemove=YES;
                }
            }
            else if(mission.type==ROUTER_MISSION_TYPE_NONE)//定时任务
            {
                seconds=[KATDateUtil difSecondsFromTime:mission.createTime toTime:[KATDateUtil now]];
            }
            
            
            if(seconds>=0 && seconds>=mission.duration)//执行
            {
                //先删除后执行
                [KATRouter removeMission:mission.name];
                
                if(mission.observer && mission.sel && _classMap[mission.observer])
                {
                    UIViewController *vc=_instanceMap[mission.observer];//获取实例
                    
                    if(!vc || ![vc isKindOfClass:[UIViewController class]])//不存在或者被释放则创建
                    {
                        Class cls=NSClassFromString(_classMap[mission.observer]);
                        
                        if(cls)
                        {
                            vc=[[[cls alloc] init] autorelease];
                            
                            //关联host
                            objc_setAssociatedObject(vc, kRouterKeyHost, mission.observer, OBJC_ASSOCIATION_COPY_NONATOMIC);
                            
                            _instanceMap[mission.observer]=vc;
                            
                            //挂钩支持屏幕方向
                            [KATRouter hookSupportedOrientationsWithVC:vc];
                            
                            //值容器表
                            if(!_valueMap[mission.observer])
                            {
                                _valueMap[mission.observer]=[KATHashMap hashMap];
                            }
                        }
                        else
                        {
                            vc=nil;
                        }
                    }
                    
                    SEL selector=NSSelectorFromString(mission.sel);
                    
                    if(vc && [vc respondsToSelector:selector])
                    {
                        [vc performSelectorOnMainThread:selector withObject:nil waitUntilDone:NO];
                    }
                }
                
                //执行过的都删除
                needRemove=YES;
            }
            else
            {
                //释放
                if(needRemove)
                {
                    [KATRouter removeMission:mission.name];
                }
            }
        }
           
        //当没有需要执行的任务且没有定时器动作时，关闭定时器
        if(_durationMissions.length<=0 && !_timerAction)
        {
            [self stopDurationMissionTimer];
        }
    });
}


//启动时长任务定时器
- (void)startDurationMissionTimer
{
    if(!_durationMissionsTimer)
    {
        self.durationMissionsTimer=[NSTimer timerWithTimeInterval:_timerInterval target:self selector:@selector(executeDurationMissions) userInfo:nil repeats:YES];
        
        //标记为common modes的模式：UITrackingRunLoopMode和NSDefaultRunLoopMode兼容
        [[NSRunLoop mainRunLoop] addTimer:_durationMissionsTimer forMode:NSRunLoopCommonModes];
    }
}


//关闭时长任务定时器
- (void)stopDurationMissionTimer
{
    if(_durationMissionsTimer)//取消定时器
    {
        [_durationMissionsTimer invalidate];
        
        self.durationMissionsTimer=nil;
    }
}


//添加历史事件发生次数任务(到达该次数则触发，可设置触发次数)
+ (void)addMission:(NSString *)mission withEvent:(NSString *)event forCount:(unsigned int)count observer:(NSString *)observerHost selector:(NSString *)selector andTimes:(unsigned int)times
{
    KATRouter *router=[self sharedRouter];
    
    if(!router.countMissions)
    {
        [router loadMissions];
    }
    
    if(mission && event && observerHost && selector)
    {
        if([KATRouter hasMission:mission])
        {
            return;
        }
        
        //创建日志动作
        KATRouterMission *mis=[KATRouterMission mission];
        mis.name=mission;
        mis.type=ROUTER_MISSION_TYPE_HISTORY;
        mis.event=event;
        mis.count=count;
        mis.observer=observerHost;
        mis.sel=selector;
        mis.times=times;
        
        router.countMissions[mission]=mis;
        
        //覆盖其他两个map
        router.durationMissions[mission]=nil;
        router.daysMissions[mission]=nil;
    }
}


//添加历史事件数组发生总数任务(到达该次数则触发，可设置触发次数)
+ (void)addMission:(NSString *)mission withEvents:(KATArray<NSString *> *)events forCount:(unsigned int)count observer:(NSString *)observerHost selector:(NSString *)selector andTimes:(unsigned int)times
{
    KATRouter *router=[self sharedRouter];
    
    if(!router.countMissions)
    {
        [router loadMissions];
    }
    
    if(mission && events && events.length>0 && observerHost && selector)
    {
        if([KATRouter hasMission:mission])
        {
            return;
        }
        
        //创建日志动作
        KATRouterMission *mis=[KATRouterMission mission];
        mis.name=mission;
        mis.type=ROUTER_MISSION_TYPE_EVENTS_HISTORY;
        mis.events=events;
        mis.count=count;
        mis.observer=observerHost;
        mis.sel=selector;
        mis.times=times;
        
        router.countMissions[mission]=mis;
        
        //覆盖其他两个map
        router.durationMissions[mission]=nil;
        router.daysMissions[mission]=nil;
    }
}


//添加当日事件发生次数任务(到达该次数则触发，可设置触发次数)
+ (void)addMission:(NSString *)mission byDayUsingWithEvent:(NSString *)event forCount:(unsigned int)count observer:(NSString *)observerHost selector:(NSString *)selector andTimes:(unsigned int)times
{
    KATRouter *router=[self sharedRouter];
    
    if(!router.countMissions)
    {
        [router loadMissions];
    }
    
    if(mission && event && observerHost && selector)
    {
        if([KATRouter hasMission:mission])
        {
            return;
        }
        
        //创建日志动作
        KATRouterMission *mis=[KATRouterMission mission];
        mis.name=mission;
        mis.type=ROUTER_MISSION_TYPE_DAY_USING;
        mis.event=event;
        mis.count=count;
        mis.observer=observerHost;
        mis.sel=selector;
        mis.times=times;
        
        router.countMissions[mission]=mis;
        
        //覆盖其他两个map
        router.durationMissions[mission]=nil;
        router.daysMissions[mission]=nil;
    }
}


//添加当日事件数组发生总数任务(到达该次数则触发，可设置触发次数)
+ (void)addMission:(NSString *)mission byDayUsingWithEvents:(KATArray<NSString *> *)events forCount:(unsigned int)count observer:(NSString *)observerHost selector:(NSString *)selector andTimes:(unsigned int)times
{
    KATRouter *router=[self sharedRouter];
    
    if(!router.countMissions)
    {
        [router loadMissions];
    }
    
    if(mission && events && events.length>0 && observerHost && selector)
    {
        if([KATRouter hasMission:mission])
        {
            return;
        }
        
        //创建日志动作
        KATRouterMission *mis=[KATRouterMission mission];
        mis.name=mission;
        mis.type=ROUTER_MISSION_TYPE_EVENTS_DAY_USING;
        mis.events=events;
        mis.count=count;
        mis.observer=observerHost;
        mis.sel=selector;
        mis.times=times;
        
        router.countMissions[mission]=mis;
        
        //覆盖其他两个map
        router.durationMissions[mission]=nil;
        router.daysMissions[mission]=nil;
    }
}


//添加app使用时事件发生次数任务(到达该次数则触发，可设置触发次数)
+ (void)addMission:(NSString *)mission byAppUsingWithEvent:(NSString *)event forCount:(unsigned int)count observer:(NSString *)observerHost selector:(NSString *)selector andTimes:(unsigned int)times
{
    KATRouter *router=[self sharedRouter];
    
    if(!router.countMissions)
    {
        [router loadMissions];
    }
    
    if(mission && event && observerHost && selector)
    {
        if([KATRouter hasMission:mission])
        {
            return;
        }
        
        //创建日志动作
        KATRouterMission *mis=[KATRouterMission mission];
        mis.name=mission;
        mis.type=ROUTER_MISSION_TYPE_APP_USING;
        mis.event=event;
        mis.count=count;
        mis.observer=observerHost;
        mis.sel=selector;
        mis.times=times;
        
        router.countMissions[mission]=mis;
        
        //覆盖其他两个map
        router.durationMissions[mission]=nil;
        router.daysMissions[mission]=nil;
    }
}


//添加app使用时事件数组发生总数任务(到达该次数则触发，可设置触发次数)
+ (void)addMission:(NSString *)mission byAppUsingWithEvents:(KATArray<NSString *> *)events forCount:(unsigned int)count observer:(NSString *)observerHost selector:(NSString *)selector andTimes:(unsigned int)times
{
    KATRouter *router=[self sharedRouter];
    
    if(!router.countMissions)
    {
        [router loadMissions];
    }
    
    if(mission && events && events.length>0 && observerHost && selector)
    {
        if([KATRouter hasMission:mission])
        {
            return;
        }
        
        //创建日志动作
        KATRouterMission *mis=[KATRouterMission mission];
        mis.name=mission;
        mis.type=ROUTER_MISSION_TYPE_EVENTS_APP_USING;
        mis.events=events;
        mis.count=count;
        mis.observer=observerHost;
        mis.sel=selector;
        mis.times=times;
        
        router.countMissions[mission]=mis;
        
        //覆盖其他两个map
        router.durationMissions[mission]=nil;
        router.daysMissions[mission]=nil;
    }
}


//执行次数数类型的任务(内部方法)
- (void)executeCountMissionsWithEvent:(NSString *)event
{
    if(!event)
    {
        return;
    }
    
    if(!_countMissions)
    {
        [self loadMissions];
    }
    
    KATArray<KATRouterMission *> *missions=[_countMissions allValues];
    
    //遍历执行
    for(KATRouterMission *mission in missions)
    {
        //触发条件
        if((mission.event && [mission.event isEqualToString:event]) || (mission.events && [mission.events hasMember:event]))
        {
            BOOL needRemove=NO;
            int count=-1;//使用次数
            
            //不存在该host则释放
            if(!mission.observer || !_classMap[mission.observer])
            {
                needRemove=YES;
            }
            
            if(mission.type==ROUTER_MISSION_TYPE_HISTORY)//历史
            {
                count=[KATRouter countInHistoryWithEvent:mission.event];
            }
            else if(mission.type==ROUTER_MISSION_TYPE_DAY_USING)//当日使用
            {
                count=[KATRouter countInDayUsingWithEvent:mission.event];
            }
            else if(mission.type==ROUTER_MISSION_TYPE_APP_USING)//app使用事件
            {
                count=[KATRouter countInAppUsingWithEvent:mission.event];
            }
            else if(mission.type==ROUTER_MISSION_TYPE_EVENTS_HISTORY)//事件数组历史总数
            {
                count=[KATRouter countInHistoryWithEvents:mission.events];
            }
            else if(mission.type==ROUTER_MISSION_TYPE_EVENTS_DAY_USING)//事件数组当日总数
            {
                count=[KATRouter countInDayUsingWithEvents:mission.events];
            }
            else if(mission.type==ROUTER_MISSION_TYPE_EVENTS_APP_USING)//事件数组app使用时总数
            {
                count=[KATRouter countInAppUsingWithEvents:mission.events];
            }
            
            if(count>=0 && count>=mission.count)//执行
            {
                //执行次数减少一次
                mission.times--;
                
                //执行次数少于1则释放
                if(mission.times<=0)
                {
                    //先删除后执行
                    [KATRouter removeMission:mission.name];
                }
                
                if(mission.observer && mission.sel && _classMap[mission.observer])
                {
                    UIViewController *vc=_instanceMap[mission.observer];//获取实例
                    
                    if(!vc || ![vc isKindOfClass:[UIViewController class]])//不存在或者被释放则创建
                    {
                        Class cls=NSClassFromString(_classMap[mission.observer]);
                        
                        if(cls)
                        {
                            vc=[[[cls alloc] init] autorelease];
                            
                            //关联host
                            objc_setAssociatedObject(vc, kRouterKeyHost, mission.observer, OBJC_ASSOCIATION_COPY_NONATOMIC);
                            
                            _instanceMap[mission.observer]=vc;
                            
                            //挂钩支持屏幕方向
                            [KATRouter hookSupportedOrientationsWithVC:vc];
                            
                            //值容器表
                            if(!_valueMap[mission.observer])
                            {
                                _valueMap[mission.observer]=[KATHashMap hashMap];
                            }
                        }
                        else
                        {
                            vc=nil;
                        }
                    }
                    
                    SEL selector=NSSelectorFromString(mission.sel);
                    
                    if(vc && [vc respondsToSelector:selector])
                    {
                        [vc performSelectorOnMainThread:selector withObject:nil waitUntilDone:NO];
                    }
                }
            }
            else
            {
                //释放
                if(needRemove)
                {
                    [KATRouter removeMission:mission.name];
                }
            }
        }
    }
}


//判断是否已经添加了该任务
+ (BOOL)hasMission:(NSString *)mission
{
    if(mission)
    {
        KATRouter *router=[self sharedRouter];
        
        if([router.daysMissions hasKey:mission])
        {
            return YES;
        }
        
        if([router.durationMissions hasKey:mission])
        {
            return YES;
        }
        
        if([router.countMissions hasKey:mission])
        {
            return YES;
        }
    }
    
    return NO;
}


//删除任务
+ (void)removeMission:(NSString *)mission
{
    if(mission)
    {
        KATRouter *router=[self sharedRouter];
        
        router.daysMissions[mission]=nil;
        router.durationMissions[mission]=nil;
        router.countMissions[mission]=nil;
    }
}


//清除所有任务
+ (void)clearMissions
{
    KATRouter *router=[self sharedRouter];
    
    [router.daysMissions clear];
    [router.durationMissions clear];
    [router.countMissions clear];
}


#pragma -mark 路由(跳转)

//禁用路由(调用该方法后，路由将无法进行，直到启用路由)(在禁用期间的所有路由行为都将被取消)
+ (void)disableRouting
{
    KATRouter *router=[KATRouter sharedRouter];
    
    router.isDisabled=YES;
}


//启用路由(默认为启用)
+ (void)enableRouting
{
    KATRouter *router=[KATRouter sharedRouter];
    
    router.isDisabled=NO;
}


//暂停路由(调用该方法后，路由将无法进行，直到恢复路由，恢复后，原先的路由行为将继续执行)
+ (void)pauseRouting
{
    KATRouter *router=[KATRouter sharedRouter];
    
    router.isWaitting=YES;
}


//恢复路由
+ (void)resumeRouting
{
    KATRouter *router=[KATRouter sharedRouter];
    
    router.isWaitting=NO;
}


//路由
+ (void)routeWithURI:(NSString *)URI
{
    KATRouter *router=[KATRouter sharedRouter];
    
    if(router.routeWithURIAction)
    {
        URI=[KATURIParser URIWithMap:router.routeWithURIAction([KATURIParser parseURI:URI],nil)];
    }
    
    if(URI)
    {
        [self routeWithURI:URI selector:nil object:nil  addition:nil forward:YES andHandle:nil];
    }
}


//路由
+ (void)routeWithURI:(NSString *)URI addition:(id)addition
{
    KATRouter *router=[KATRouter sharedRouter];
    
    if(router.routeWithURIAction)
    {
        URI=[KATURIParser URIWithMap:router.routeWithURIAction([KATURIParser parseURI:URI],addition)];
    }
    
    if(URI)
    {
        [self routeWithURI:URI selector:nil object:nil  addition:addition forward:YES andHandle:nil];
    }
}


//路由
+ (void)routeWithURI:(NSString *)URI andHandle:(void (^)(void))handle
{
    [self routeWithURI:URI selector:nil object:nil  addition:nil forward:YES andHandle:handle];
}


//路由
+ (void)routeWithURI:(NSString *)URI addition:(id)addition andHandle:(void (^)(void))handle
{
    [self routeWithURI:URI selector:nil object:nil addition:addition forward:YES andHandle:handle];
}


//路由(全参数)
+ (void)routeWithURI:(NSString *)URI selector:(SEL)sel object:(id)obj addition:(id)addition andHandle:(void (^)(void))handle
{
    [self routeWithURI:URI selector:sel object:obj addition:addition forward:YES andHandle:handle];
}


//路由可用状态检测(内部方法)
+ (BOOL)_routingAvailable
{
    KATRouter *router=[self sharedRouter];
    
    __block BOOL result=YES;
    
    dispatch_sync(dispatch_get_main_queue(), ^
    {
        if(!router.topVC)//还没有root
        {
            result=YES;
        }
        else if(router.isDisabled || router.isWaitting || router.isRouting || router.isPresenting || (router.topVC!=[KATAppUtil topViewController] && router.topVC!=nil))
        {
            result=NO;
        }
    });
    
    return result;
}


//路由(内部方法，带有前进后退标记)
+ (void)routeWithURI:(NSString *)URI selector:(SEL)sel object:(id)obj addition:(id)addition forward:(BOOL)forward andHandle:(void (^)(void))handle
{
    KATRouter *router=[self sharedRouter];
    
//    if(router.isRouting || router.isPresenting)
//    {
//        return;
//    }
    
    dispatch_async(router.queueRouting, ^
    {
        double waitDuration=0;
        
        while(waitDuration<router.routingWaitDuration)
        {
            if(router.isDisabled)//禁用跳转
            {
                return;
            }
            
            if([self _routingAvailable])//可跳转
            {
                break;
            }
            
            if(router.isWaitting)//在等待
            {
                if(!forward)//回退
                {
                    return;
                }
            }
            else//非等待，正常阻塞
            {
                waitDuration+=ROUTER_ROUTING_TEST_INTERVAL;
            }
            
            [NSThread sleepForTimeInterval:ROUTER_ROUTING_TEST_INTERVAL];
        }
        
        if(![self _routingAvailable])
        {
            return;
        }
    
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(router.routingProtectionDuration * NSEC_PER_SEC)), dispatch_get_main_queue(), ^
        {
            router.isLoaded=YES;
            
            //解析URI
            KATHashMap *uri=[KATURIParser parseURI:URI];
            
            //host
            NSString *host=uri[kURIKeyHost];
            
            if(host && router.classMap[host])//存在host
            {
                router.isRouting=YES;
                
                router.showingHost=host;
                
                //多例处理
                NSRange range=[router.showingHost rangeOfString:kRouterMultipleHostMark];
                
                if(range.length>0)
                {
                    router.showingHost=[router.showingHost substringToIndex:range.location];
                }
                
                //顶层VC
                UIViewController *topVC=router.topVC?router.topVC:[KATAppUtil topViewController];
                
                //顶层host
                NSString *topHost=objc_getAssociatedObject(topVC, kRouterKeyHost);
                
                //非路由器顶层
                if(topVC!=[KATAppUtil topViewController])
                {
                    router.isRouting=NO;
                    
                    return;
                }
                
                //无法跳转到顶层
                if([kRouterRootHost isEqualToString:router.showingHost])
                {
                    router.isRouting=NO;
                    
                    return;
                }
                
                //无法跳自己
                if([host isEqualToString:topHost])
                {
                    if(![router.routingWithMultipleInstanceHosts getValueWithKey:host])
                    {
                        router.isRouting=NO;
                        
                        return;
                    }
                }
                
                //路由允许回调
                if([topVC conformsToProtocol:@protocol(KATRouterDelegate)] && [topVC respondsToSelector:@selector(allowRoutingWithValues:)])
                {
                    //设置传递值
                    KATHashMap *values=[KATHashMap hashMap];
                    
                    values[kRouterKeyScheme]=uri[kURIKeyScheme];
                    values[kRouterKeyUser]=uri[kURIKeyUser];
                    values[kRouterKeyHost]=uri[kURIKeyHost];
                    values[kRouterKeyPath]=uri[kURIKeyPath];
                    values[kRouterKeyPort]=uri[kURIKeyPort];
                    values[kRouterKeyFragment]=uri[kURIKeyFragment];
                    values[kRouterKeyAddition]=addition;
                    values[kRouterKeyBackward]=[NSString stringWithFormat:@"%i",(!forward)];
                    [values putWithMap:uri[kURIKeyQuery]];
                    
                    BOOL allowed=[(id<KATRouterDelegate>)topVC allowRoutingWithValues:values];
                    
                    if(!allowed)
                    {
                        router.isRouting=NO;
                        
                        return;
                    }
                }
                
                
                //侧滑背景截图
                UIView *bgView=nil;
                
                if(forward && topHost)
                {
                    bgView=[topVC.view snapshotViewAfterScreenUpdates:NO];
                    bgView.bounds=RECT(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
                    
                    if(bgView)
                    {
                        //侧滑背景表
                        router.slideBackgroundViews[topHost]=bgView;
                    }
                    
                    //回退堆栈
                    [router.backwardStack put:topHost];
                }
                
                //跳转背景截图
                UIView *fromView=[topVC.view snapshotViewAfterScreenUpdates:NO];
                fromView.bounds=RECT(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
                
                //传递的截图
                UIImage *fromHostSnapshot=nil;
                
                //需要接收截图
                if(router.requiredSnapshotHosts[router.showingHost])
                {
                    fromHostSnapshot=[KATImageUtil imageFromView:topVC.view];
                }
                
                
                //解析fromHost和toHost
                NSString *fromHost=topHost;
                
                range=[fromHost rangeOfString:kRouterMultipleHostMark];
                
                if(range.length>0)//多例对象
                {
                    fromHost=[fromHost substringToIndex:range.location];
                }
                
                NSString *toHost=host;
                
                range=[toHost rangeOfString:kRouterMultipleHostMark];
                
                if(range.length>0)//多例对象
                {
                    toHost=[toHost substringToIndex:range.location];
                }
                
                
                //消失
                if(topVC!=router.rootVC)
                {
                    //路由消失回调
                    if([topVC conformsToProtocol:@protocol(KATRouterDelegate)] && [topVC respondsToSelector:@selector(routingDismissWithValues:backward:)])
                    {
                        //设置传递值
                        KATHashMap *values=[KATHashMap hashMap];
                        
                        values[kRouterKeyScheme]=uri[kURIKeyScheme];
                        values[kRouterKeyUser]=uri[kURIKeyUser];
                        values[kRouterKeyHost]=fromHost;
                        values[kRouterKeyPath]=uri[kURIKeyPath];
                        values[kRouterKeyPort]=uri[kURIKeyPort];
                        values[kRouterKeyFragment]=uri[kURIKeyFragment];
                        values[kRouterKeyAddition]=addition;
                        values[kRouterKeyToHost]=toHost;
                        values[kRouterKeyBackward]=[NSString stringWithFormat:@"%i",(!forward)];
                        values[kRouterKeyFromHostSnapshot]=fromHostSnapshot;
                        [values putWithMap:uri[kURIKeyQuery]];
                        
                        [(id<KATRouterDelegate>)topVC routingDismissWithValues:values backward:!forward];
                    }
                    
                    router.isDismissing=YES;
                    
                    //顶层消失
                    [topVC dismissViewControllerAnimated:NO completion:^
                    {
                        router.isDismissing=NO;
                    }];
                }
                
                
                //屏幕方向校正
                [router adjustOritation];
                
                
                //截图位置方向调整
                fromView.center=POINT(SCREEN_WIDTH*0.5, SCREEN_HEIGHT*0.5);
                fromView.layer.transform=CATransform3DIdentity;
                
                if(fabs(fromView.bounds.size.height-SCREEN_HEIGHT)>1.0)//横竖不一致
                {
                    if(fromView.bounds.size.height>SCREEN_HEIGHT)//横屏转竖屏
                    {
                        fromView.layer.transform=CATransform3DRotate(CATransform3DIdentity, -M_PI*0.5, 0.0, 0.0, 1.0);
                    }
                    else//竖屏转横屏
                    {
                        fromView.layer.transform=CATransform3DRotate(CATransform3DIdentity, M_PI*0.5, 0.0, 0.0, 1.0);
                    }
                }
                
                //根VC添加截图
                [router.rootVC.view addSubview:fromView];
                
                
                //侧滑
                BOOL needSlide=NO;
                
                //是否新建实例
                BOOL isNewInstance=NO;
                
                //存在表中
                if([router.routingWithNewInstanceHosts getValueWithKey:router.showingHost])
                {
                    isNewInstance=YES;
                }
                
                //传递的参数
                if(uri[kURIKeyQuery] && uri[kURIKeyQuery][router.routingWithNewInstanceKey])
                {
                    isNewInstance=[uri[kURIKeyQuery][router.routingWithNewInstanceKey] boolValue];
                }
                
                
                //是否创建多例
                BOOL isMultipleInstance=NO;
                
                if(forward)//回退模式下不创建多例
                {
                    //存在表中
                    if([router.routingWithMultipleInstanceHosts getValueWithKey:host])
                    {
                        isMultipleInstance=YES;
                    }
                    
                    //传递的参数
                    if(uri[kURIKeyQuery] && uri[kURIKeyQuery][router.routingWithMultipleInstanceKey])
                    {
                        isMultipleInstance=[uri[kURIKeyQuery][router.routingWithMultipleInstanceKey] boolValue];
                    }
                }
                
                
                //跳转的实例
                UIViewController *vc=router.instanceMap[host];
                
                
                if(isMultipleInstance)//创建多例
                {
                    //添加参数
                    if(!uri[kURIKeyQuery])
                    {
                        uri[kURIKeyQuery]=[KATHashMap hashMap];
                    }
                    
                    uri[kURIKeyQuery][router.routingWithMultipleInstanceKey]=@"1";
                    
                    if(vc && [vc isKindOfClass:[UIViewController class]] && [router.backwardStack hasMember:host])//已经存在实例则
                    {
                        Class cls=NSClassFromString(router.classMap[host]);
                        
                        if(cls)
                        {
                            vc=[[[cls alloc] init] autorelease];
                            
                            //生成新的host
                            NSString *newHost=[NSString stringWithFormat:@"%@%@%i",host,kRouterMultipleHostMark,arc4random()%100000000];
                            
                            while(router.classMap[newHost])
                            {
                                newHost=[NSString stringWithFormat:@"%@%@%i",host,kRouterMultipleHostMark,arc4random()%100000000];
                            }
                            
                            //判断侧滑条件
                            if(!forward && _router.slideGestures[host])
                            {
                                needSlide=YES;
                            }
                            
                            //注册
                            [KATRouter registerInstance:vc withHost:newHost];
                        }
                        else
                        {
                            vc=nil;
                        }
                    }
                }
                else if(isNewInstance)//新建实例
                {
                    //添加参数
                    if(!uri[kURIKeyQuery])
                    {
                        uri[kURIKeyQuery]=[KATHashMap hashMap];
                    }
                    
                    uri[kURIKeyQuery][router.routingWithNewInstanceKey]=@"1";
                    
                    //判断侧滑条件
                    if(_router.slideGestures[host])
                    {
                        needSlide=YES;
                    }
                    
                    //释放实例
                    [KATRouter releaseInstanceWithHost:host];
                    
                    vc=nil;
                }
                
                
                if(!vc || ![vc isKindOfClass:[UIViewController class]])//不存在或者被释放则创建
                {
                    Class cls=NSClassFromString(router.classMap[host]);
                    
                    if(cls)
                    {
                        vc=[[[cls alloc] init] autorelease];
                        
                        //关联host
                        objc_setAssociatedObject(vc, kRouterKeyHost, host, OBJC_ASSOCIATION_COPY_NONATOMIC);
                        
                        router.instanceMap[host]=vc;
                        
                        //挂钩支持屏幕方向
                        [KATRouter hookSupportedOrientationsWithVC:vc];
                        
                        //值容器表
                        if(!router.valueMap[host])
                        {
                            router.valueMap[host]=[KATHashMap hashMap];
                        }
                    }
                    else
                    {
                        vc=nil;
                    }
                }

                
                if(vc && [vc isKindOfClass:[UIViewController class]])
                {
                    //跳转动作
                    if(router.routeAction)
                    {
                        //设置传递值
                        KATHashMap *values=[KATHashMap hashMap];
                        
                        values[kRouterKeyScheme]=uri[kURIKeyScheme];
                        values[kRouterKeyUser]=uri[kURIKeyUser];
                        values[kRouterKeyHost]=toHost;
                        values[kRouterKeyPath]=uri[kURIKeyPath];
                        values[kRouterKeyPort]=uri[kURIKeyPort];
                        values[kRouterKeyFragment]=uri[kURIKeyFragment];
                        values[kRouterKeyAddition]=addition;
                        values[kRouterKeyFromHost]=fromHost;
                        values[kRouterKeyBackward]=[NSString stringWithFormat:@"%i",(!forward)];
                        values[kRouterKeyFromHostSnapshot]=fromHostSnapshot;
                        [values putWithMap:uri[kURIKeyQuery]];
                        
                        router.routeAction(values);
                    }
                    
                    
                    //路由前回调
                    if([vc conformsToProtocol:@protocol(KATRouterDelegate)] && [vc respondsToSelector:@selector(routingBeginWithValues:backward:)])
                    {
                        //设置传递值
                        KATHashMap *values=[KATHashMap hashMap];
                        
                        values[kRouterKeyScheme]=uri[kURIKeyScheme];
                        values[kRouterKeyUser]=uri[kURIKeyUser];
                        values[kRouterKeyHost]=toHost;
                        values[kRouterKeyPath]=uri[kURIKeyPath];
                        values[kRouterKeyPort]=uri[kURIKeyPort];
                        values[kRouterKeyFragment]=uri[kURIKeyFragment];
                        values[kRouterKeyAddition]=addition;
                        values[kRouterKeyFromHost]=fromHost;
                        values[kRouterKeyBackward]=[NSString stringWithFormat:@"%i",(!forward)];
                        values[kRouterKeyFromHostSnapshot]=fromHostSnapshot;
                        [values putWithMap:uri[kURIKeyQuery]];
                        
                        [(id<KATRouterDelegate>)vc routingBeginWithValues:values backward:!forward];
                    }
                    
                    BOOL isTabHost=NO;//是否为标签关联host
                    
                    //判断是否与标签栏关联
                    if(router.tabBar)
                    {
                        for(int i=0;i<router.tabBar.hostArray.length;i++)
                        {
                            KATHashMap *hostMap=[KATURIParser parseURI:router.tabBar.hostArray[i]];
                            
                            if([host isEqualToString:hostMap[kURIKeyHost]])
                            {
                                isTabHost=YES;
                                
                                router.tabBar.selectedIndex=i;
                                
                                if(uri[kURIKeyQuery] && uri[kURIKeyQuery][kTabBarClickingKey])
                                {
                                    //从tab栏点击跳转，不做处理
                                }
                                else
                                {
                                    [router.tabBar update];
                                }
                                
                                if([router.tabBar isInstanceInTab:topVC] || topVC==router.rootVC)//tab切换跳转
                                {
                                    //设置跳转风格
                                    if(!uri[kURIKeyQuery])
                                    {
                                        uri[kURIKeyQuery]=[KATHashMap hashMapWithCapacity:10 andMaxUsage:70];
                                    }
                                    
                                    ((KATHashMap *)uri[kURIKeyQuery])[router.transitionStyleKey]=[NSString stringWithFormat:@"%lu",(unsigned long)router.tabBar.transitionStyle];
                                    ((KATHashMap *)uri[kURIKeyQuery])[router.transitionDurationKey]=[NSString stringWithFormat:@"%lf",router.tabBar.transitionDuration];
                                }
                                
                                [self showTabBar];
                                
                                break;
                            }
                        }
                        
                        //非标签关联host自动隐藏标签栏
                        if(router.isAutoHidingTabBar && !isTabHost)
                        {
                            [self hideTabBar];
                        }
                    }
                    
                    
                    if(router.navBar)//带导航栏
                    {
                        BOOL showNavBar=NO;
                        
                        //导航栏代理
                    
                        //初始化
                        router.navBar.hasBackButton=YES;
                        router.navBar.title=nil;
                        router.navBar.icon=nil;
                        router.navBar.button=nil;
                        
                        //是否显示
                        if([vc respondsToSelector:@selector(isShownNavBar:)])
                        {
                            showNavBar=[(UIViewController<KATRouterDelegate> *)vc isShownNavBar:router.navBar];
                        }
                        
                        //返回按钮
                        if([vc respondsToSelector:@selector(hideBackButtonInNavBar:)])
                        {
                            router.navBar.hasBackButton=![(UIViewController<KATRouterDelegate> *)vc hideBackButtonInNavBar:router.navBar];
                        }
                        
                        //标题
                        if([vc respondsToSelector:@selector(titleInNavBar:)])
                        {
                            router.navBar.title=[(UIViewController<KATRouterDelegate> *)vc titleInNavBar:router.navBar];
                        }
                        
                        //图标
                        if([vc respondsToSelector:@selector(iconInNavBar:)])
                        {
                            router.navBar.icon=[(UIViewController<KATRouterDelegate> *)vc iconInNavBar:router.navBar];
                        }
                        
                        //按钮
                        if([vc respondsToSelector:@selector(buttonInNavBar:)])
                        {
                            router.navBar.button=[(UIViewController<KATRouterDelegate> *)vc buttonInNavBar:router.navBar];
                        }
                        
                        if(showNavBar)
                        {
                            [self showNavBar];
                        }
                        else
                        {
                            [self hideNavBar];
                        }
                    }
                    
                    //设置传递值
                    KATHashMap *values=[KATHashMap hashMap];
                    
                    values[kRouterKeyScheme]=uri[kURIKeyScheme];
                    values[kRouterKeyUser]=uri[kURIKeyUser];
                    values[kRouterKeyHost]=uri[kURIKeyHost];
                    values[kRouterKeyPath]=uri[kURIKeyPath];
                    values[kRouterKeyPort]=uri[kURIKeyPort];
                    values[kRouterKeyFragment]=uri[kURIKeyFragment];
                    values[kRouterKeyAddition]=addition;
                    values[kRouterKeyFromHost]=topHost;
                    values[kRouterKeyBackward]=[NSString stringWithFormat:@"%i",(!forward)];
                    values[kRouterKeyFromHostSnapshot]=fromHostSnapshot;
                    
                    [values putWithMap:uri[kURIKeyQuery]];
                    
                    //默认转场风格
                    KATRouterTransitionStyle style=router.transitionStyle;
                    
                    //默认转场时长
                    double duration=router.transitionDuration;
                    
                    //host默认的转场风格
                    if(forward)//前进
                    {
                        if(router.transitionHosts[host])
                        {
                            style=(KATRouterTransitionStyle)[router.transitionHosts[host] longLongValue];
                        }
                    }
                    else//后退
                    {
                        if(router.transitionHosts[fromHost])
                        {
                            style=(KATRouterTransitionStyle)[router.transitionHosts[fromHost] longLongValue];
                        }
                        
                        if(topVC && objc_getAssociatedObject(topVC, kRouterKeyTransitionStyle))//与之前进入的风格对应
                        {
                            style=(KATRouterTransitionStyle)[objc_getAssociatedObject(topVC, kRouterKeyTransitionStyle) longLongValue];
                        }
                        
                        if(topVC && objc_getAssociatedObject(topVC, kRouterKeyTransitionDuration))//与之前进入的时长对应
                        {
                            duration=[objc_getAssociatedObject(topVC, kRouterKeyTransitionDuration) doubleValue];
                        }
                    }
                    
                    //设置单次转场风格
                    if(values[router.transitionStyleKey])
                    {
                        style=[values[router.transitionStyleKey] intValue];
                    }
                    
                    //设置单次转场时长
                    if(values[router.transitionDurationKey])
                    {
                        duration=[values[router.transitionDurationKey] doubleValue];
                    }
                    
                    //最大值
                    if(duration>ROUTER_TRANSITION_DURATION_MAX)
                    {
                        duration=ROUTER_TRANSITION_DURATION_MAX;
                    }
                    
                    //添加转场风格和时长，以便回退时使用相同的转场风格和时长
                    if(forward && vc)
                    {
                        //关联转场动画
                        objc_setAssociatedObject(vc, kRouterKeyTransitionStyle, [NSString stringWithFormat:@"%lu",(unsigned long)style], OBJC_ASSOCIATION_COPY_NONATOMIC);
                        
                        //关联转场时长
                        objc_setAssociatedObject(vc, kRouterKeyTransitionDuration, [NSString stringWithFormat:@"%lf",duration], OBJC_ASSOCIATION_COPY_NONATOMIC);
                    }
                    
                    //清除可能残存的动画
                    [router.window.layer removeAllAnimations];
                    
                    //是否有自定义的转场效果
                    BOOL hasTransition=NO;
                    
                    if(style==KATRouterTransitionStyleNavHorizontal || style==KATRouterTransitionStyleNavVertical)//导航效果的转场动画
                    {
                        hasTransition=YES;
                    }
                    
                    if(hasTransition)
                    {
                        if(!router.navTransition)
                        {
                            router.navTransition=[KATNavTransition transition];
                        }
                        
                        if(forward)
                        {
                            router.navTransition.isDismissAnimation=NO;
                        }
                        else
                        {
                            router.navTransition.isDismissAnimation=YES;
                        }
                        
                        if(style==KATRouterTransitionStyleNavHorizontal)
                        {
                            router.navTransition.isVerticalAnimation=NO;
                        }
                        else
                        {
                            router.navTransition.isVerticalAnimation=YES;
                        }
                        
                        router.navTransition.duration=duration;
                        
                        vc.transitioningDelegate=router.navTransition;
                        vc.modalPresentationStyle=UIModalPresentationFullScreen;
                    }
                    else
                    {
                        vc.transitioningDelegate=nil;
                        
                        //设置动画效果
                        if(topVC!=vc)
                        {
                            [router.window.layer addAnimation:[self transtionWithStyle:style duration:duration andForward:forward] forKey:nil];
                        }
                    }
                    
                    
                    if(forward || isNewInstance || isMultipleInstance)//添加手势条件
                    {
                        //侧滑相关
                        if(!isTabHost)//tab栏相关的host不能侧滑
                        {
                            if(isMultipleInstance)//多例
                            {
                                if(forward)
                                {
                                    if([router.slideHosts getValueWithKey:host])//存在侧滑表中
                                    {
                                        needSlide=YES;
                                    }
                                    else if(router.slideAutoSetting)//自动设置
                                    {
                                        if(style==KATRouterTransitionStyleNavHorizontal)//出现动画为水平滑进
                                        {
                                            needSlide=YES;
                                        }
                                    }
                                }
                                
                                if(needSlide)
                                {
                                    NSString *newHost=objc_getAssociatedObject(vc, kRouterKeyHost);
                                    
                                    //添加手势
                                    [router addSlideGuestureToHost:newHost];
                                }
                            }
                            else
                            {
                                if([router.slideHosts getValueWithKey:host])//存在侧滑表中
                                {
                                    needSlide=YES;
                                }
                                else if(router.slideAutoSetting)//自动设置
                                {
                                    if(style==KATRouterTransitionStyleNavHorizontal)//出现动画为水平滑进
                                    {
                                        needSlide=YES;
                                    }
                                }
                                
                                if(needSlide)
                                {
                                    //添加手势
                                    [router addSlideGuestureToHost:host];
                                }
                            }
                        }
                    }
                    
                    
                    //模态显示
                    if(topVC!=vc)//非顶层VC
                    {
                        //日志
                        router.lastURI=URI;
                        [router _saveHostLog];
                        [router _loadHostLog];

                        //VC添加到根VC
                        [router.rootVC presentViewController:vc animated:hasTransition completion:^
                        {
                            //校正屏幕方向
                            [router adjustOritation];
                            
                            //执行block
                            if(handle)
                            {
                                handle();
                            }
                            
                            //执行方法
                            if(sel)
                            {
                                if([vc respondsToSelector:sel])
                                {
                                    [vc performSelectorOnMainThread:sel withObject:obj waitUntilDone:NO];
                                }
                            }
                            
                            //路由完成回调
                            if([vc conformsToProtocol:@protocol(KATRouterDelegate)] && [vc respondsToSelector:@selector(routingFinishWithValues:backward:)])
                            {
                                [(id<KATRouterDelegate>)vc routingFinishWithValues:values backward:!forward];
                            }
                            
                            
                            //自动释放实例
                            if([router.backwardStack hasMember:topHost])
                            {
                                //还在返回栈，则不释放
                            }
                            else//没在返回栈上则释放
                            {
                                if(![router.alwaysRetainedHosts getValueWithKey:topHost])//不在总是持有表中
                                {
                                    //移除侧滑手势
                                    [_router removeSlideGuestureFromhHost:topHost];
                                    
                                    //释放实例
                                    [KATRouter releaseInstance:topVC];
                                }
                                
                                //释放截图
                                router.slideBackgroundViews[topHost]=nil;
                            }
                            
                            
                            //删除截图
                            [fromView removeFromSuperview];
                            
                            //根背景
                            router.rootBg.layer.transform=CATransform3DIdentity;
                            
                            router.topVC=vc;
                            router.isRouting=NO;
                        }];
                    }
                    else
                    {
                        //校正屏幕方向
                        [router adjustOritation];
                        
                        router.isRouting=NO;
                        
                        //回退堆栈
                        if(forward)
                        {
                            [router.backwardStack get];
                        }
                        
                        //释放截图
                        if(![_router.backwardStack hasMember:topHost])
                        {
                            _router.slideBackgroundViews[topHost]=nil;
                        }
                    }
                }
            }
            else
            {
                router.isRouting=NO;
            }
            
        });
    });
}


//校正屏幕方向
- (void)adjustOritation
{
    if([KATAppUtil topViewController]!=_rootVC && [KATRouter topViewController]!=[KATAppUtil topViewController])
    {
        if(MAX([KATAppUtil topViewController].view.bounds.size.width, [KATAppUtil topViewController].view.bounds.size.height)>MAX(SCREEN_WIDTH, SCREEN_HEIGHT)-0.5 || MIN([KATAppUtil topViewController].view.bounds.size.width, [KATAppUtil topViewController].view.bounds.size.height)>MIN(SCREEN_WIDTH, SCREEN_HEIGHT)-0.5)//全屏VC不处理
        {
            return;
        }
    }
    
    KATRouter *router=[KATRouter sharedRouter];
    
    //屏幕方向
    if(![router.freeOrientationHosts getValueWithKey:router.showingHost])//非自由方向
    {
        if(router.isLandscapeOrientationDefault)//默认横屏
        {
            if([router.portraitOrientationHosts getValueWithKey:router.showingHost])//竖屏
            {
                if([KATAppUtil currentOrientation]!=UIInterfaceOrientationPortrait && [KATAppUtil currentOrientation]!=UIInterfaceOrientationPortraitUpsideDown)
                {
                    if([KATAppUtil currentOrientation]==UIInterfaceOrientationLandscapeLeft || [KATAppUtil currentOrientation]==UIInterfaceOrientationLandscapeRight)
                    {
                        [KATAppUtil setOrientation:UIInterfaceOrientationPortrait];
                    }
                    else
                    {
                        if(router.isCurrentLandscapeOrientation)
                        {
                            [KATAppUtil setOrientation:UIInterfaceOrientationPortrait];
                        }
                    }
                }
                
                router.isCurrentLandscapeOrientation=NO;
            }
            else//设置横屏
            {
                if([KATAppUtil currentOrientation]!=UIInterfaceOrientationLandscapeLeft && [KATAppUtil currentOrientation]!=UIInterfaceOrientationLandscapeRight)
                {
                    if([KATAppUtil currentOrientation]==UIInterfaceOrientationPortrait || [KATAppUtil currentOrientation]==UIInterfaceOrientationPortraitUpsideDown)
                    {
                        [KATAppUtil setOrientation:UIInterfaceOrientationLandscapeRight];
                    }
                    else
                    {
                        if(!router.isCurrentLandscapeOrientation)
                        {
                            [KATAppUtil setOrientation:UIInterfaceOrientationLandscapeRight];
                        }
                    }
                }
                
                router.isCurrentLandscapeOrientation=YES;
            }
        }
        else//默认竖屏
        {
            if([router.landscapeOrientationHosts getValueWithKey:router.showingHost])//横屏
            {
                if([KATAppUtil currentOrientation]!=UIInterfaceOrientationLandscapeLeft && [KATAppUtil currentOrientation]!=UIInterfaceOrientationLandscapeRight)
                {
                    if([KATAppUtil currentOrientation]==UIInterfaceOrientationPortrait || [KATAppUtil currentOrientation]==UIInterfaceOrientationPortraitUpsideDown)
                    {
                        [KATAppUtil setOrientation:UIInterfaceOrientationLandscapeRight];
                    }
                    else
                    {
                        if(!router.isCurrentLandscapeOrientation)
                        {
                            [KATAppUtil setOrientation:UIInterfaceOrientationLandscapeRight];
                        }
                    }
                }
                
                router.isCurrentLandscapeOrientation=YES;
            }
            else//设置竖屏 
            {
                if([KATAppUtil currentOrientation]!=UIInterfaceOrientationPortrait && [KATAppUtil currentOrientation]!=UIInterfaceOrientationPortraitUpsideDown)
                {
                    if([KATAppUtil currentOrientation]==UIInterfaceOrientationLandscapeLeft || [KATAppUtil currentOrientation]==UIInterfaceOrientationLandscapeRight)
                    {
                        [KATAppUtil setOrientation:UIInterfaceOrientationPortrait];
                    }
                    else
                    {
                        if(router.isCurrentLandscapeOrientation)
                        {
                            [KATAppUtil setOrientation:UIInterfaceOrientationPortrait];
                        }
                    }
                }
                
                router.isCurrentLandscapeOrientation=NO;
            }
        }
    }
}



//获取转场动画（内部方法）
+ (CATransition *)transtionWithStyle:(KATRouterTransitionStyle)style duration:(double)duration andForward:(BOOL)forward
{
    switch(style)
    {
        case KATRouterTransitionStyleNone:
            
            return nil;
            
            
        case KATRouterTransitionStyleFade:
            
            return [KATSprite transitionWithType:@"fade" subtype:nil duration:duration delay:0];
            
            
        case KATRouterTransitionStyleMoveHorizontal:
            
            return [KATSprite transitionWithType:@"movein" subtype:forward?kCATransitionFromRight:kCATransitionFromLeft duration:duration delay:0];
            
            
        case KATRouterTransitionStyleMoveVertical:
            
            return [KATSprite transitionWithType:@"movein" subtype:forward?kCATransitionFromTop:kCATransitionFromBottom duration:duration delay:0];
            
            
        case KATRouterTransitionStylePushHorizontal:
            
            return [KATSprite transitionWithType:@"push" subtype:forward?kCATransitionFromRight:kCATransitionFromLeft duration:duration delay:0];
            
            
        case KATRouterTransitionStylePushVertical:
            
            return [KATSprite transitionWithType:@"push" subtype:forward?kCATransitionFromTop:kCATransitionFromBottom duration:duration delay:0];
            
            
        case KATRouterTransitionStyleRevealHorizontal:
            
            return [KATSprite transitionWithType:@"reveal" subtype:forward?kCATransitionFromRight:kCATransitionFromLeft duration:duration delay:0];
            
            
        case KATRouterTransitionStyleRevealVertical:
            
            return [KATSprite transitionWithType:@"reveal" subtype:forward?kCATransitionFromTop:kCATransitionFromBottom duration:duration delay:0];
            
            
        case KATRouterTransitionStyleCubeHorizontal:
            
            return [KATSprite transitionWithType:@"cube" subtype:forward?kCATransitionFromRight:kCATransitionFromLeft duration:duration delay:0];
            
            
        case KATRouterTransitionStyleCubeVertical:
            
            return [KATSprite transitionWithType:@"cube" subtype:forward?kCATransitionFromTop:kCATransitionFromBottom duration:duration delay:0];
            
            
        case KATRouterTransitionStyleFlipHorizontal:
            
            return [KATSprite transitionWithType:@"oglFlip" subtype:forward?kCATransitionFromRight:kCATransitionFromLeft duration:duration delay:0];
            
            
        case KATRouterTransitionStyleFlipVertical:
            
            return [KATSprite transitionWithType:@"oglFlip" subtype:forward?kCATransitionFromTop:kCATransitionFromBottom duration:duration delay:0];
            
            
        case KATRouterTransitionStyleSuck:
            
            return [KATSprite transitionWithType:@"suckEffect" subtype:nil duration:duration delay:0];
            
            
        case KATRouterTransitionStyleRipple:
            
            return [KATSprite transitionWithType:@"rippleEffect" subtype:nil duration:duration delay:0];
            
            
        case KATRouterTransitionStyleCurlLeft:
            
            return [KATSprite transitionWithType:forward?@"pageCurl":@"pageUnCurl" subtype:kCATransitionFromLeft duration:duration delay:0];
            
            
        case KATRouterTransitionStyleCurlRight:
            
            return [KATSprite transitionWithType:forward?@"pageCurl":@"pageUnCurl" subtype:kCATransitionFromRight duration:duration delay:0];
            
            
        case KATRouterTransitionStyleCurlBottom:
            
            return [KATSprite transitionWithType:forward?@"pageCurl":@"pageUnCurl" subtype:kCATransitionFromBottom duration:duration delay:0];
            
        case KATRouterTransitionStyleNavVertical:
        case KATRouterTransitionStyleNavHorizontal:
            
            break;
            
    }
    
    return nil;
}


//回退
+ (void)backward
{
    [self backwardWithQuery:nil addition:nil andHandle:nil];
}


//回退(query不带问号)
+ (void)backwardWithQuery:(NSString *)query
{
    [self backwardWithQuery:query addition:nil andHandle:nil];
}


//回退
+ (void)backwardWithAddition:(id)addition
{
    [self backwardWithQuery:nil addition:addition andHandle:nil];
}


//回退
+ (void)backwardWithHandle:(void (^)(void))handle
{
    [self backwardWithQuery:(nil) addition:nil andHandle:handle];
}


//回退(全参数)
+ (void)backwardWithQuery:(NSString *)query addition:(id)addition andHandle:(void (^)(void))handle;
{
    KATRouter *router=[self sharedRouter];
    
//    if(router.isDisabled || router.isWaitting || router.isRouting)
    if(router.isBacking || router.isDisabled || router.isWaitting || router.isRouting || router.isPresenting || (router.topVC!=[KATAppUtil topViewController] && router.topVC!=nil))
    {
        return;
    }
    
    if(router.backwardStack.length>0)
    {
        NSString *host=[router.backwardStack toper];
        
        if([kRouterRootHost isEqualToString:host])//无法返回顶层
        {
            return;
        }
        
        NSString *URI=nil;
        
        if(query && query.length>0)
        {
            URI=[NSString stringWithFormat:@"%@?%@",[router.backwardStack get],query];
        }
        else
        {
            URI=[router.backwardStack get];
        }
        
        router.isBacking=YES;
        
        GCD_MAIN_AFTER(0.5,
        {
            router.isBacking=NO;
        });
        
        //跳转
        [self routeWithURI:URI selector:nil object:nil addition:addition forward:NO andHandle:handle];
    }
}


//回退到指定的URI(该host必须在回退栈上才会执行，若栈上有多个该host，则回退到最顶端的host，执行时会清除栈顶到host之间的所有回退节点)
+ (void)backwardWithURI:(NSString *)URI addition:(id)addition andHandle:(void (^)(void))handle;
{
    if(URI)
    {
        KATRouter *router=[self sharedRouter];
        
//        if(router.isDisabled || router.isWaitting || router.isRouting)
        if(router.isBacking || router.isDisabled || router.isWaitting || router.isRouting || router.isPresenting || (router.topVC!=[KATAppUtil topViewController] && router.topVC!=nil))
        {
            return;
        }
        
        //解析
        KATHashMap *uri=[KATURIParser parseURI:URI];
        NSString *host=uri[kURIKeyHost];

        if(host && [router.backwardStack hasMember:host])//该host存在回退栈中
        {
            while(router.backwardStack.length>0)
            {
                //获取栈顶元素
                NSString *backHost=[router.backwardStack get];
                
                
                //解析多例
                NSRange range=[backHost rangeOfString:kRouterMultipleHostMark];
                
                if(range.length>0)
                {
                    backHost=[backHost substringToIndex:range.location];
                }
                
                
                if([host isEqualToString:backHost])//找到
                {
                    router.isBacking=YES;
                    
                    GCD_MAIN_AFTER(0.5,
                    {
                        router.isBacking=NO;
                    });
                    
                    [self routeWithURI:URI selector:nil object:nil addition:addition forward:NO andHandle:handle];
                    
                    break;
                }
                else//需要清除的元素
                {
                    //判断是否需要释放
                    if([router.alwaysRetainedHosts getValueWithKey:backHost] || [router.backwardStack hasMember:backHost])
                    {
                        //还在回退栈上或者在总是持有表中则不释放
                    }
                    else
                    {
                        if(router.instanceMap[backHost]!=router.topVC)
                        {
                            //释放实例
                            [KATRouter releaseInstanceWithHost:backHost];
                            
                            //释放截图
                            _router.slideBackgroundViews[backHost]=nil;
                        }
                    }
                }
            }
        }
    }
}


//路由到当前host(不带参数刷新当前host的方法，会触发回调，用于恢复导航栏、标签栏等操作)
+ (void)routeCurrent
{
    [self routeWithURI:[NSString stringWithFormat:@"%@?%@=0",[KATRouter topHost],[KATRouter routingWithMultipleInstanceKey]]];
}


//路由到当前tab栏选中的host
+ (void)routeToTabBarSelectdHost
{
    NSString *host=[KATRouter hostInSelectedTab];
    
    if(host)
    {
        [KATRouter routeWithURI:host];
    }
}


//路由到当前tab栏选中的URI
+ (void)routeToTabBarSelectdURI
{
    NSString *URI=[KATRouter URIInSelectedTab];
    
    if(URI)
    {
        [KATRouter routeWithURI:URI];
    }
}


//退回到当前tab栏选中的host
+ (void)backToTabBarSelectdHost
{
    NSString *host=[KATRouter hostInSelectedTab];
    
    if(host)
    {
        [KATRouter backwardWithURI:host addition:nil andHandle:nil];
    }
}


//退回到当前tab栏选中的URI
+ (void)backToTabBarSelectdURI
{
    NSString *URI=[KATRouter URIInSelectedTab];
    
    if(URI)
    {
        [KATRouter backwardWithURI:URI addition:nil andHandle:nil];
    }
}



#pragma -mark 侧滑回退

//添加侧滑回退的host数组
+ (void)addSlideHosts:(KATArray<NSString *> *)hosts
{
    if(hosts && hosts.length>0)
    {
        KATRouter *router=[self sharedRouter];
        
        for(NSString *host in hosts)
        {
            [router.slideHosts putWithKey:host andValue:host];
        }
    }
}


//添加侧滑回退的host
+ (void)addSlideHost:(NSString *)host
{
    if(host)
    {
        KATRouter *router=[self sharedRouter];
        
        [router.slideHosts putWithKey:host andValue:host];
    }
}


//删除侧滑回退的host
+ (void)removeSlideHost:(NSString *)host
{
    if(host)
    {
        KATRouter *router=[self sharedRouter];
        
        [router removeSlideGuestureFromhHost:host];
        
        [router.slideHosts deleteValueWithKey:host];
    }
}


//清除侧滑回退的host
+ (void)clearSlideHosts
{
    KATRouter *router=[self sharedRouter];
    
    for(NSString *host in [router.slideHosts allKeys])
    {
        if(router.instanceMap[host])
        {
            //移除手势
            [router removeSlideGuestureFromhHost:host];
        }
    }
    
    [router.slideHosts clear];
}


//添加禁止侧滑回退的host数组
+ (void)addSlideDisabledHosts:(KATArray<NSString *> *)hosts
{
    if(hosts && hosts.length>0)
    {
        KATRouter *router=[self sharedRouter];
        
        for(NSString *host in hosts)
        {
            [router.slideDisabledHosts putWithKey:host andValue:host];
        }
    }
}


//添加禁止侧滑回退的host
+ (void)addSlideDisabledHost:(NSString *)host
{
    if(host)
    {
        KATRouter *router=[self sharedRouter];
        
        [router.slideDisabledHosts putWithKey:host andValue:host];
    }
}


//删除禁止侧滑回退的host
+ (void)removeSlideDisabledHost:(NSString *)host
{
    if(host)
    {
        KATRouter *router=[self sharedRouter];
        
        [router.slideDisabledHosts deleteValueWithKey:host];
    }
}


//清除禁止侧滑回退的host
+ (void)clearSlideDisabledHosts
{
    KATRouter *router=[self sharedRouter];
    
    [router.slideDisabledHosts clear];
}


//设置侧滑完成进度点(0~1之间 默认0.4,即超过宽度的40%)
+ (void)setSlideFinishProgress:(float)progress
{
    KATRouter *router=[self sharedRouter];
    
    if(progress<0.0)
    {
        progress=0.0;
    }
    
    if(progress>1.0)
    {
        progress=1.0;
    }
    
    router.slideFinishProgress=progress;
}


//设置侧滑手势完成条件的滑动尾速(默认为每帧16点)
+ (void)setSlideFinishSpeed:(float)speed
{
    KATRouter *router=[self sharedRouter];
    
    if(speed<0.0)
    {
        speed=0.0;
    }
    
    router.slideFinishSpeed=speed;
}


//设置侧滑手势起始点X坐标位置(0~1之间,默认0.5,即左半屏)
+ (void)setSlideStartXPoint:(float)xPoint
{
    KATRouter *router=[self sharedRouter];
    
    if(xPoint<0.0)
    {
        xPoint=0.0;
    }
    
    if(xPoint>1.0)
    {
        xPoint=1.0;
    }
    
    router.slideStartXPoint=xPoint;
}


//设置水平滑动动画效果的host是否自动带侧滑交互(默认是)
+ (void)setSlideAutoSetting:(BOOL)autoSetting
{
    KATRouter *router=[self sharedRouter];
    
    router.slideAutoSetting=autoSetting;
}


//添加滑动手势(内部方法)
- (void)addSlideGuestureToHost:(NSString *)host
{
    if(host && _router.instanceMap[host])
    {
        if(!_router.slideGestures[host])
        {
            UIPanGestureRecognizer *slideGesture=[[[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(slideHandle:)] autorelease];
            
            _router.slideGestures[host]=slideGesture;
            
            [_router.instanceMap[host].view addGestureRecognizer:slideGesture];
//            [_router.instanceMap[host].view performSelectorOnMainThread:@selector(addGestureRecognizer:) withObject:slideGesture waitUntilDone:NO];
        }
    }
}


//删除滑动手势(内部方法)
- (void)removeSlideGuestureFromhHost:(NSString *)host
{
    if(host && _router.instanceMap[host])
    {
        if(_router.slideGestures[host])
        {
            UIPanGestureRecognizer *slideGesture=_router.slideGestures[host];
            
            [_router.instanceMap[host].view removeGestureRecognizer:slideGesture];
            
            [_router.slideGestures deleteValueWithKey:host];
        }
    }
}


//滑动开始(内部方法)
- (void)slideStart
{
    if(_router.isDisabled || _router.isWaitting || _router.isRouting || [_router.slideDisabledHosts getValueWithKey:[KATRouter currentHost]])
    {
        return;
    }
    
    if(_router.backwardStack.length>0 && !_router.isRouting)
    {
        NSString *host=[_router.backwardStack toper];
        
        if([kRouterRootHost isEqualToString:host])//无法返回顶层
        {
            return;
        }
        
        _router.slideBackgroundView=_router.slideBackgroundViews[host];
        
        if(_router.slideBackgroundView)//获取背景成功
        {
            _router.slideBackgroundView.center=POINT(SCREEN_WIDTH*0.5, SCREEN_HEIGHT*0.5);
            
            //判断是否需要旋转
            _router.slideBackgroundView.layer.transform=CATransform3DIdentity;
            
            if(fabs(_router.slideBackgroundView.bounds.size.height-[KATAppUtil topViewController].view.bounds.size.height)>1.0)//横竖不一致
            {
                if(_router.slideBackgroundView.bounds.size.height>[KATAppUtil topViewController].view.bounds.size.height)//横屏转竖屏
                {
                    _router.slideBackgroundView.layer.transform=CATransform3DRotate(CATransform3DIdentity, -M_PI*0.5, 0.0, 0.0, 1.0);
                }
                else//竖屏转横屏
                {
                     _router.slideBackgroundView.layer.transform=CATransform3DRotate(CATransform3DIdentity, M_PI*0.5, 0.0, 0.0, 1.0);
                }
            }
            
            _router.slideBackgroundView.center=POINT(SCREEN_WIDTH*0.5-MIN(SCREEN_WIDTH, SCREEN_HEIGHT)*0.2, _router.slideBackgroundView.center.y);
            
            //阴影
            if(!_router.slideShadowView)
            {
                _router.slideShadowView=[[[UIView alloc] init] autorelease];
                _router.slideShadowView.backgroundColor=KCOLOR_SHADOW_LIGHT;
            }
            
            _router.slideShadowView.frame=_router.slideBackgroundView.frame;
            
            //顶层VC
            UIViewController *topVC=[KATAppUtil topViewController];
            
            //截图
            _router.slideForegroundView=[topVC.view snapshotViewAfterScreenUpdates:NO];
            
            //添加图层
            [topVC.view addSubview:_router.slideBackgroundView];
            [topVC.view addSubview:_router.slideShadowView];
            [topVC.view addSubview:_router.slideForegroundView];
            
            _router.isSliding=YES;
        }
    }
    
}


//滑动中(内部方法)
- (void)slideWithDistance:(double)distance
{
    if(_router.isSliding)
    {
        //更新速度
        _router.slideSpeed=distance-_router.slideDistance;
        
        //更新距离
        _router.slideDistance=distance;
        
        
        if(_router.slideDistance>0)
        {
            //位移
            _router.slideForegroundView.center=POINT(SCREEN_WIDTH*0.5+_router.slideDistance, _router.slideForegroundView.center.y);
            _router.slideBackgroundView.center=POINT(SCREEN_WIDTH*0.5-MIN(SCREEN_WIDTH, SCREEN_HEIGHT)*0.2*(1.0-_router.slideDistance/SCREEN_WIDTH), _router.slideBackgroundView.center.y);
            
            //阴影
            _router.slideShadowView.alpha=1.0-(_router.slideDistance/_router.slideForegroundView.bounds.size.width);
            
            //导航栏
            if(_router.navBar)
            {
                _router.navBar.opacity=1.0-(_router.slideDistance/_router.slideForegroundView.bounds.size.width);
            }
        }
        else
        {
            //位移
            _router.slideForegroundView.center=POINT(SCREEN_WIDTH*0.5, _router.slideForegroundView.center.y);
            
            //阴影
            _router.slideShadowView.alpha=1.0;
            
            //导航栏
            if(_router.navBar)
            {
                _router.navBar.opacity=1.0;
            }
        }
    }
}


//滑动取消(内部方法)
- (void)slideCancel
{
    if(_router.isSliding)
    {
        //动画
        [UIView animateWithDuration:_router.transitionDuration*(_router.slideDistance/SCREEN_WIDTH) animations:^
        {
            _router.slideForegroundView.center=POINT(SCREEN_WIDTH*0.5, _router.slideForegroundView.center.y);
            _router.slideBackgroundView.center=POINT(SCREEN_WIDTH*0.5, _router.slideBackgroundView.center.y);
            _router.slideShadowView.alpha=1.0;
            
            //导航栏
            if(_router.navBar)
            {
                _router.navBar.opacity=1.0;
            }
        }
        completion:^(BOOL finished)
        {
            //重置
            [_router restoreSlide];
        }];
    }
}


//滑动完成(内部方法)
- (void)slideFinish
{
    if(_router.isSliding)
    {
        //动画
        [UIView animateWithDuration:_router.transitionDuration*(1.0-_router.slideDistance/SCREEN_WIDTH) animations:^
        {
            _router.slideForegroundView.center=POINT(SCREEN_WIDTH*1.5, _router.slideForegroundView.center.y);
            _router.slideBackgroundView.center=POINT(SCREEN_WIDTH*0.5, _router.slideBackgroundView.center.y);
            _router.slideShadowView.alpha=0.0;
            
            //导航栏
            if(_router.navBar)
            {
                _router.navBar.opacity=0.0;
            }
        }
        completion:^(BOOL finished)
        {
            //路由跳转
            _router.isRouting=YES;
            
            //顶层VC
            UIViewController *topVC=_router.topVC?_router.topVC:[KATAppUtil topViewController];
            
            //顶层host
            NSString *topHost=objc_getAssociatedObject(topVC, kRouterKeyHost);
            
            if(_router.backwardStack.length>0)
            {
                NSString *host=[_router.backwardStack toper];
                
                _router.showingHost=host;
                
                //多例处理
                NSRange range=[_router.showingHost rangeOfString:kRouterMultipleHostMark];
                
                if(range.length>0)
                {
                    _router.showingHost=[_router.showingHost substringToIndex:range.location];
                }
                
                
                if([kRouterRootHost isEqualToString:_router.showingHost])//无法返回顶层
                {
                    return;
                }
                
                NSString *URI=[_router.backwardStack get];
                
                //解析URI
                KATHashMap *uri=[KATURIParser parseURI:URI];
                
                
                //跳转背景截图
                UIView *fromView=[topVC.view snapshotViewAfterScreenUpdates:NO];
                fromView.bounds=RECT(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
                
                //传递的截图
                UIImage *fromHostSnapshot=nil;
                
                //需要接收截图
                if(_router.requiredSnapshotHosts[_router.showingHost])
                {
                    fromHostSnapshot=[KATImageUtil imageFromView:topVC.view];
                }
                
                
                //解析fromHost和toHost
                NSString *fromHost=topHost;
                
                range=[fromHost rangeOfString:kRouterMultipleHostMark];
                
                if(range.length>0)//多例对象
                {
                    fromHost=[fromHost substringToIndex:range.location];
                }
                
                NSString *toHost=host;
                
                range=[toHost rangeOfString:kRouterMultipleHostMark];
                
                if(range.length>0)//多例对象
                {
                    toHost=[toHost substringToIndex:range.location];
                }
                
                
                //校正屏幕方向
                [_router adjustOritation];
                
                
                //是否支持侧滑
                BOOL needSlide=NO;
                
                //是否新建实例
                BOOL isNewInstance=NO;
                
                //存在表中
                if([_router.routingWithNewInstanceHosts getValueWithKey:host])
                {
                    isNewInstance=YES;
                }
                
                //传递的参数
                if(uri[kURIKeyQuery] && uri[kURIKeyQuery][_router.routingWithNewInstanceKey])
                {
                    isNewInstance=[uri[kURIKeyQuery][_router.routingWithNewInstanceKey] boolValue];
                }
                
                
                UIViewController *vc=_router.instanceMap[host];//获取实例
                
                //若新建实例则先释放
                if(isNewInstance)
                {
                    //添加参数
                    if(!uri[kURIKeyQuery])
                    {
                        uri[kURIKeyQuery]=[KATHashMap hashMap];
                    }
                    
                    uri[kURIKeyQuery][_router.routingWithNewInstanceKey]=@"1";
                    
                    //判断侧滑条件
                    if(_router.slideGestures[host])
                    {
                        needSlide=YES;
                    }
                    
                    //释放实例
                    [KATRouter releaseInstanceWithHost:host];
                    
                    vc=nil;
                }
                
                
                if(!vc || ![vc isKindOfClass:[UIViewController class]])//不存在或者被释放则创建
                {
                    Class cls=NSClassFromString(_router.classMap[host]);
                    
                    if(cls)
                    {
                        vc=[[[cls alloc] init] autorelease];
                        
                        //关联host
                        objc_setAssociatedObject(vc, kRouterKeyHost, host, OBJC_ASSOCIATION_COPY_NONATOMIC);
                        
                        _router.instanceMap[host]=vc;
                        
                        //挂钩支持屏幕方向
                        [KATRouter hookSupportedOrientationsWithVC:vc];
                        
                        //值容器表
                        if(!_router.valueMap[host])
                        {
                            _router.valueMap[host]=[KATHashMap hashMap];
                        }
                        
                    }
                    else
                    {
                        vc=nil;
                    }
                }
                
                
                
                if(vc && [vc isKindOfClass:[UIViewController class]])
                {
                    //跳转动作
                    if(_router.routeAction)
                    {
                        //设置传递值
                        KATHashMap *values=[KATHashMap hashMap];
                        
                        values[kRouterKeyScheme]=uri[kURIKeyScheme];
                        values[kRouterKeyUser]=uri[kURIKeyUser];
                        values[kRouterKeyHost]=toHost;
                        values[kRouterKeyPath]=uri[kURIKeyPath];
                        values[kRouterKeyPort]=uri[kURIKeyPort];
                        values[kRouterKeyFragment]=uri[kURIKeyFragment];
                        values[kRouterKeyFromHost]=fromHost;
                        values[kRouterKeyBackward]=@"1";
                        values[kRouterKeyFromHostSnapshot]=fromHostSnapshot;
                        [values putWithMap:uri[kURIKeyQuery]];
                        
                        _router.routeAction(values);
                    }
                    
                    
                    //路由前回调
                    if([vc conformsToProtocol:@protocol(KATRouterDelegate)] && [vc respondsToSelector:@selector(routingBeginWithValues:backward:)])
                    {
                        //设置传递值
                        KATHashMap *values=[KATHashMap hashMap];
                        
                        values[kRouterKeyScheme]=uri[kURIKeyScheme];
                        values[kRouterKeyUser]=uri[kURIKeyUser];
                        values[kRouterKeyHost]=toHost;
                        values[kRouterKeyPath]=uri[kURIKeyPath];
                        values[kRouterKeyPort]=uri[kURIKeyPort];
                        values[kRouterKeyFragment]=uri[kURIKeyFragment];
                        values[kRouterKeyFromHost]=fromHost;
                        values[kRouterKeyBackward]=@"1";
                        values[kRouterKeyFromHostSnapshot]=fromHostSnapshot;
                        [values putWithMap:uri[kURIKeyQuery]];
                        
                        [(id<KATRouterDelegate>)vc routingBeginWithValues:values backward:YES];
                    }
                    
                    BOOL isTabHost=NO;//是否为标签关联host
                    
                    //判断是否与标签栏关联
                    if(_router.tabBar)
                    {
                        for(int i=0;i<_router.tabBar.hostArray.length;i++)
                        {
                            KATHashMap *hostMap=[KATURIParser parseURI:_router.tabBar.hostArray[i]];
                            
                            if([host isEqualToString:hostMap[kURIKeyHost]])
                            {
                                isTabHost=YES;
                                
                                _router.tabBar.selectedIndex=i;
                                
                                [KATRouter showTabBar];
                                
                                break;
                            }
                        }
                        
                        //非标签关联host自动隐藏标签栏
                        if(_router.isAutoHidingTabBar && !isTabHost)
                        {
                            [KATRouter hideTabBar];
                        }
                    }
                    
                    
                    if(_router.navBar)//带导航栏
                    {
                        BOOL showNavBar=NO;
                        
                        //导航栏代理
                        
                        //初始化
                        _router.navBar.hasBackButton=YES;
                        _router.navBar.title=nil;
                        _router.navBar.icon=nil;
                        _router.navBar.button=nil;
                        
                        //是否显示
                        if([vc respondsToSelector:@selector(isShownNavBar:)])
                        {
                            showNavBar=[(UIViewController<KATRouterDelegate> *)vc isShownNavBar:_router.navBar];
                        }
                        
                        //返回按钮
                        if([vc respondsToSelector:@selector(hideBackButtonInNavBar:)])
                        {
                            _router.navBar.hasBackButton=![(UIViewController<KATRouterDelegate> *)vc hideBackButtonInNavBar:_router.navBar];
                        }
                        
                        //标题
                        if([vc respondsToSelector:@selector(titleInNavBar:)])
                        {
                            _router.navBar.title=[(UIViewController<KATRouterDelegate> *)vc titleInNavBar:_router.navBar];
                        }
                        
                        //图标
                        if([vc respondsToSelector:@selector(iconInNavBar:)])
                        {
                            _router.navBar.icon=[(UIViewController<KATRouterDelegate> *)vc iconInNavBar:_router.navBar];
                        }
                        
                        //按钮
                        if([vc respondsToSelector:@selector(buttonInNavBar:)])
                        {
                            _router.navBar.button=[(UIViewController<KATRouterDelegate> *)vc buttonInNavBar:_router.navBar];
                        }
                        
                        if(showNavBar)
                        {
                            [KATRouter showNavBar];
                        }
                        else
                        {
                            [KATRouter hideNavBar];
                        }
                        
                    }
                    
                    //设置传递值
                    KATHashMap *values=[KATHashMap hashMap];
                    
                    values[kRouterKeyScheme]=uri[kURIKeyScheme];
                    values[kRouterKeyUser]=uri[kURIKeyUser];
                    values[kRouterKeyHost]=uri[kURIKeyHost];
                    values[kRouterKeyPath]=uri[kURIKeyPath];
                    values[kRouterKeyPort]=uri[kURIKeyPort];
                    values[kRouterKeyFragment]=uri[kURIKeyFragment];
                    values[kRouterKeyFromHost]=topHost;
                    values[kRouterKeyBackward]=@"1";
                    values[kRouterKeyFromHostSnapshot]=fromHostSnapshot;
                    
                    [values putWithMap:uri[kURIKeyQuery]];
                    
                    
                    if(isNewInstance)//添加手势条件
                    {
                        //侧滑相关
                        if(!isTabHost)//tab栏相关的host不能侧滑
                        {
                            if([_router.slideHosts getValueWithKey:host])//存在侧滑表中
                            {
                                needSlide=YES;
                            }
                        }
                        else
                        {
                            needSlide=NO;
                        }
                        
                        if(needSlide)
                        {
                            [_router addSlideGuestureToHost:host];
                        }
                    }
                    
                    
                    //模态显示
                    if(topVC!=vc)//非顶层VC
                    {
                        //日志
                        _router.lastURI=URI;
                        [_router _saveHostLog];
                        [_router _loadHostLog];
                        
                        
                        //根VC添加截图
                        [_router.rootVC.view addSubview:fromView];
                        
                        //路由消失回调
                        if([topVC conformsToProtocol:@protocol(KATRouterDelegate)] && [topVC respondsToSelector:@selector(routingDismissWithValues:backward:)])
                        {
                            //设置传递值
                            KATHashMap *values=[KATHashMap hashMap];
                            
                            values[kRouterKeyScheme]=uri[kURIKeyScheme];
                            values[kRouterKeyUser]=uri[kURIKeyUser];
                            values[kRouterKeyHost]=fromHost;
                            values[kRouterKeyPath]=uri[kURIKeyPath];
                            values[kRouterKeyPort]=uri[kURIKeyPort];
                            values[kRouterKeyFragment]=uri[kURIKeyFragment];
                            values[kRouterKeyToHost]=toHost;
                            values[kRouterKeyBackward]=@"1";
                            values[kRouterKeyFromHostSnapshot]=fromHostSnapshot;
                            [values putWithMap:uri[kURIKeyQuery]];
                            
                            [(id<KATRouterDelegate>)topVC routingDismissWithValues:values backward:YES];
                        }
                        
                        _router.isDismissing=YES;
                        
                        //顶层VC消失
                        [topVC dismissViewControllerAnimated:NO completion:^
                        {
                            //重置
                            [_router restoreSlide];
                            
                            //VC添加到根VC
                            [_router.rootVC presentViewController:vc animated:NO completion:^
                            {
                                //校正屏幕方向
                                [_router adjustOritation];
                                
                                //路由完成回调
                                if([vc conformsToProtocol:@protocol(KATRouterDelegate)] && [vc respondsToSelector:@selector(routingFinishWithValues:backward:)])
                                {
                                    [(id<KATRouterDelegate>)vc routingFinishWithValues:values backward:YES];
                                }
                                
                                //删除截图
                                [fromView removeFromSuperview];
                            }];
                            
                            //自动释放实例
                            if([_router.backwardStack hasMember:topHost])
                            {
                                //还在返回栈，则不释放
                            }
                            else//没在返回栈上则释放
                            {
                                if(![_router.alwaysRetainedHosts getValueWithKey:topHost])//不在总是持有表中
                                {
                                    //移除侧滑手势
                                    [_router removeSlideGuestureFromhHost:topHost];
                                     
                                    //释放实例
                                    [KATRouter releaseInstance:topVC];
                                }
                                
                                //释放截图
                                _router.slideBackgroundViews[topHost]=nil;
                            }
                             
                            _router.topVC=vc;
                            _router.isRouting=NO;
                            _router.isDismissing=NO;
                        }];
                    }
                    else
                    {
                        //校正屏幕方向
                        [_router adjustOritation];
                        
                        _router.isRouting=NO;
                        
                        //重置
                        [_router restoreSlide];
                        
                        //释放截图
                        if(![_router.backwardStack hasMember:topHost])
                        {
                            _router.slideBackgroundViews[topHost]=nil;
                        }
                    }
                }
                else
                {
                    _router.isRouting=NO;
                }
            }
            else
            {
                _router.isRouting=NO;
            }
        }];
    }
}


//重置侧滑数据(内部方法)
- (void)restoreSlide
{
    //移除图层
    [_router.slideShadowView removeFromSuperview];
    [_router.slideBackgroundView removeFromSuperview];
    [_router.slideForegroundView removeFromSuperview];
    
    //导航栏
    if(_router.navBar)
    {
        _router.navBar.opacity=1.0;
    }
    
    //数据清零
    _router.isSliding=NO;
    _router.slideDisabled=NO;
    _router.slideSpeed=0.0;
    _router.slideDistance=0.0;
}



//滑动事件(内部方法)
- (void)slideHandle:(UIPanGestureRecognizer *)pan
{
    switch(pan.state)
    {
        case UIGestureRecognizerStateBegan:
            
            if(!_router.slideDisabled)
            {
                CGPoint location=[pan locationInView:pan.view];
                
                if(location.x<=_router.slideStartXPoint*pan.view.bounds.size.width)
                {
                    [_router slideStart];
                }
            }
            
            break;
            
            
        case UIGestureRecognizerStateChanged:
            
            if(_router.isSliding)
            {
                CGPoint translatedPoint=[pan translationInView:pan.view];
                CGFloat x=translatedPoint.x;
                
                [_router slideWithDistance:x];
            }
            
            break;
            
            
        case UIGestureRecognizerStateEnded:
        case UIGestureRecognizerStateCancelled:
        case UIGestureRecognizerStateFailed:
            
            if(!_router.slideDisabled)
            {
                if(_router.slideDistance/pan.view.bounds.size.width>=_router.slideFinishProgress || _router.slideSpeed>=_router.slideFinishSpeed)
                {
                    [_router slideFinish];
                }
                else
                {
                    [_router slideCancel];
                }
            }
            
            break;
            
            
        case UIGestureRecognizerStatePossible:
            
            break;
    }
}



#pragma -mark 发送消息(不跳转，在receivedRouterMessage:回调方法中处理)

//发送消息到指定的host
+ (void)sendMessage:(KATHashMap *)message toHost:(NSString *)host
{
    if(!host || !message)
    {
        return;
    }
    
    KATRouter *router=[self sharedRouter];
    
    //当前的host
    message[kRouterKeyFromHost]=objc_getAssociatedObject([KATAppUtil topViewController], kRouterKeyHost);
    
    if(host && router.classMap[host])//存在host
    {
        UIViewController *vc=router.instanceMap[host];//获取实例
        
        if(!vc || ![vc isKindOfClass:[UIViewController class]])//不存在或者被释放则创建
        {
            Class cls=NSClassFromString(router.classMap[host]);
            
            if(cls)
            {
                vc=[[[cls alloc] init] autorelease];
                
                //关联host
                objc_setAssociatedObject(vc, kRouterKeyHost, host, OBJC_ASSOCIATION_COPY_NONATOMIC);
                
                router.instanceMap[host]=vc;
                
                //挂钩支持屏幕方向
                [KATRouter hookSupportedOrientationsWithVC:vc];
                
                //值容器表
                if(!router.valueMap[host])
                {
                    router.valueMap[host]=[KATHashMap hashMap];
                }
            }
            else
            {
                vc=nil;
            }
        }
        
        if(vc)
        {
            if([vc respondsToSelector:@selector(receivedRouterMessage:)])
            {
                [(id<KATRouterDelegate>)vc receivedRouterMessage:message];
            }
        }
    }
}


//发送消息到当前的host
+ (void)sendMessage:(KATHashMap *)message
{
    [self sendMessage:message toHost:[self currentHost]];
}


//广播消息(发送消息给所有已经实例化的Host)
+ (void)broadcastMessage:(KATHashMap *)message
{
    if(!message)
    {
        return;
    }
    
    KATRouter *router=[self sharedRouter];
    
    //当前的host
    NSString *fromHost=objc_getAssociatedObject([KATAppUtil topViewController], kRouterKeyHost);
    
    //多例处理
    NSRange range=[fromHost rangeOfString:kRouterMultipleHostMark];
    
    if(range.length>0)
    {
        fromHost=[fromHost substringToIndex:range.location];
    }
    
    message[kRouterKeyFromHost]=fromHost;
    
    
    KATArray<NSString *> *hosts=[router.classMap allKeys];
    
    //遍历执行
    for(NSString *host in hosts)
    {
        UIViewController *vc=router.instanceMap[host];//获取实例
        
        if(vc)
        {
            if([vc respondsToSelector:@selector(receivedRouterMessage:)])
            {
                [(id<KATRouterDelegate>)vc receivedRouterMessage:message];
            }
        }
    }
}


//广播指定类型的消息(发送消息给监听该类型消息的Host)
+ (void)broadcastMessage:(KATHashMap *)message withType:(NSString *)type
{
    if(!message || !type)
    {
        return;
    }
    
    
    KATRouter *router=[self sharedRouter];
    
    if(!router.messageTypeMap[type])//没有该消息类型
    {
        router.messageTypeMap[type]=[KATArray array];
    }
    
    //消息类型
    message[kRouterKeyMessageType]=type;
    
    //当前的host
    NSString *fromHost=objc_getAssociatedObject([KATAppUtil topViewController], kRouterKeyHost);
    
    //多例处理
    NSRange range=[fromHost rangeOfString:kRouterMultipleHostMark];
    
    if(range.length>0)
    {
        fromHost=[fromHost substringToIndex:range.location];
    }
    
    message[kRouterKeyFromHost]=fromHost;
    
    
    KATArray<NSString *> *hosts=[router.classMap allKeys];
    
    //遍历执行
    for(NSString *host in hosts)
    {
        //多例处理
        NSString *toHost=host;
        NSRange range=[toHost rangeOfString:kRouterMultipleHostMark];
        
        if(range.length>0)
        {
            toHost=[toHost substringToIndex:range.location];
        }
        
        if([router.messageTypeMap[type] hasMember:toHost])//存在该消息类型表中
        {
            UIViewController *vc=router.instanceMap[host];//获取实例
        
            if(!vc || ![vc isKindOfClass:[UIViewController class]])//不存在或者被释放则创建
            {
                Class cls=NSClassFromString(router.classMap[host]);
                
                if(cls)
                {
                    vc=[[[cls alloc] init] autorelease];
                    
                    //关联host
                    objc_setAssociatedObject(vc, kRouterKeyHost, host, OBJC_ASSOCIATION_COPY_NONATOMIC);
                    
                    router.instanceMap[host]=vc;
                    
                    //挂钩支持屏幕方向
                    [KATRouter hookSupportedOrientationsWithVC:vc];
                    
                    //值容器表
                    if(!router.valueMap[host])
                    {
                        router.valueMap[host]=[KATHashMap hashMap];
                    }
                }
                else
                {
                    vc=nil;
                }
            }
        
            if(vc)
            {
                if([vc respondsToSelector:@selector(receivedRouterMessage:)])
                {
                    [(id<KATRouterDelegate>)vc receivedRouterMessage:message];
                }
            }
        }
    }
}


//监听指定类型的消息(通过host指定)
+ (void)addObserverWithHost:(NSString *)host forMessageType:(NSString *)type
{
    if(!host || !type)
    {
        return;
    }
    
    KATRouter *router=[self sharedRouter];
    
    //多例处理
    NSRange range=[host rangeOfString:kRouterMultipleHostMark];
    
    if(range.length>0)
    {
        host=[host substringToIndex:range.location];
    }
    
    if(!router.messageTypeMap[type])//没有该消息类型
    {
        router.messageTypeMap[type]=[KATArray array];
    }
    
    if(![router.messageTypeMap[type] hasMember:host])
    {
        [router.messageTypeMap[type] put:host];
    }
}


//监听指定类型的消息(通过类指定)
+ (void)addObserverWithClass:(Class)cls forMessageType:(NSString *)type
{
    if(!cls || !type)
    {
        return;
    }
    
    KATRouter *router=[self sharedRouter];
    
    [self addObserverWithHost:[router.classMap getKeyWithValue:NSStringFromClass(cls)] forMessageType:type];
}


//监听指定类型的消息(通过类名指定)
+ (void)addObserverWithClassName:(NSString *)name forMessageType:(NSString *)type
{
    if(!name || !type)
    {
        return;
    }
    
    KATRouter *router=[self sharedRouter];
    
    [self addObserverWithHost:[router.classMap getKeyWithValue:name] forMessageType:type];
}


//监听指定类型的消息(通过实例指定)
+ (void)addObserverWithInstance:(UIViewController *)instance forMessageType:(NSString *)type
{
    if(!instance || !type)
    {
        return;
    }
    
    KATRouter *router=[self sharedRouter];
    
    [self addObserverWithHost:[router.instanceMap getKeyWithValue:instance] forMessageType:type];
}


//移除监听指定类型的消息(通过host移除)
+ (void)removeObserverWithHost:(NSString *)host forMessageType:(NSString *)type
{
    if(!host || !type)
    {
        return;
    }
    
    KATRouter *router=[self sharedRouter];
    
    //多例处理
    NSRange range=[host rangeOfString:kRouterMultipleHostMark];
    
    if(range.length>0)
    {
        host=[host substringToIndex:range.location];
    }
    
    if(router.messageTypeMap[type])//有该消息类型
    {
        [router.messageTypeMap[type] deleteMember:host];
    }
}


//移除监听指定类型的消息(通过类移除)
+ (void)removeObserverWithClass:(Class)cls forMessageType:(NSString *)type
{
    if(!cls || !type)
    {
        return;
    }
    
    KATRouter *router=[self sharedRouter];
    
    [self removeObserverWithHost:[router.classMap getKeyWithValue:NSStringFromClass(cls)] forMessageType:type];
}


//移除监听指定类型的消息(通过类名移除)
+ (void)removeObserverWithClassName:(NSString *)name forMessageType:(NSString *)type
{
    if(!name || !type)
    {
        return;
    }
    
    KATRouter *router=[self sharedRouter];
    
    [self removeObserverWithHost:[router.classMap getKeyWithValue:name] forMessageType:type];
}


//移除监听指定类型的消息(通过实例移除)
+ (void)removeObserverWithInstance:(UIViewController *)instance forMessageType:(NSString *)type
{
    if(!instance || !type)
    {
        return;
    }
    
    KATRouter *router=[self sharedRouter];
    
    [self removeObserverWithHost:[router.instanceMap getKeyWithValue:instance] forMessageType:type];
}


//移除所有的监听消息
+ (void)removeObserverForAllMessageTypesWithHost:(NSString *)host
{
    if(!host)
    {
        return;
    }
    
    KATRouter *router=[self sharedRouter];
    
    KATArray<KATArray<NSString *> *> *types=[router.messageTypeMap allValues];
    
    for(KATArray<NSString *> *type in types)
    {
        [type deleteMember:host];
    }
}


//清除所有的消息及监听器
+ (void)clearMessageObservers
{
    KATRouter *router=[self sharedRouter];
    
    [router.messageTypeMap clear];
}


//通过URI的方式发送消息
+ (void)noticeWithURI:(NSString *)URI
{
    if(!URI)
    {
        return;
    }
    
    KATRouter *router=[self sharedRouter];
    
    //解析URI
    KATHashMap *message=[KATURIParser parseURI:URI];
    
    //host
    NSString *host=message[kURIKeyHost];
    
    if(host && router.classMap[host])//存在host
    {
        UIViewController *vc=router.instanceMap[host];//获取实例
        
        if(!vc || ![vc isKindOfClass:[UIViewController class]])//不存在或者被释放则创建
        {
            Class cls=NSClassFromString(router.classMap[host]);
            
            if(cls)
            {
                vc=[[[cls alloc] init] autorelease];
                
                //关联host
                objc_setAssociatedObject(vc, kRouterKeyHost, host, OBJC_ASSOCIATION_COPY_NONATOMIC);
                
                router.instanceMap[host]=vc;
                
                //挂钩支持屏幕方向
                [KATRouter hookSupportedOrientationsWithVC:vc];
                
                //值容器表
                if(!router.valueMap[host])
                {
                    router.valueMap[host]=[KATHashMap hashMap];
                }
            }
            else
            {
                vc=nil;
            }
        }
        
        if(vc)
        {
            if([vc respondsToSelector:@selector(receivedRouterMessage:)])
            {
                [(id<KATRouterDelegate>)vc receivedRouterMessage:message];
            }
        }
    }
}


#pragma -mark 执行动作

//添加执行动作(重复添加会覆盖)
+ (void)addAction:(NSString *)action withObserver:(id)observer andSelector:(SEL)selector
{
    if(action && observer && selector)
    {
        KATRouter *router=[self sharedRouter];
        
        router.actionObserverMap[action]=observer;
        router.actionSelectorMap[action]=NSStringFromSelector(selector);
    }
}


//移除执行动作
+ (void)removeAction:(NSString *)action
{
    if(action)
    {
        KATRouter *router=[self sharedRouter];
        
        [router.actionObserverMap deleteValueWithKey:action];
        [router.actionSelectorMap deleteValueWithKey:action];
    }
}


//执行动作
+ (void)doAction:(NSString *)action
{
    [self doAction:action withObject:nil];
}


//执行带参数的动作
+ (void)doAction:(NSString *)action withObject:(id)obj
{
    if(action)
    {
        KATRouter *router=[self sharedRouter];
        
        if(router.actionObserverMap[action] && router.actionSelectorMap[action])
        {
            SEL sel=NSSelectorFromString(router.actionSelectorMap[action]);
            
            if([router.actionObserverMap[action] respondsToSelector:sel])
            {
                [router.actionObserverMap[action] performSelectorOnMainThread:sel withObject:obj waitUntilDone:NO];
            }
        }
    }
}


//清除所有动作
+ (void)clearActions
{
    KATRouter *router=[self sharedRouter];
    
    [router.actionObserverMap clear];
    [router.actionSelectorMap clear];
}


//添加host执行动作(重复添加会覆盖)
+ (void)addHostAction:(NSString *)action withHost:(NSString *)host andSelector:(NSString *)selector
{
    if(action && host && selector)
    {
        KATRouter *router=[self sharedRouter];
        
        router.hostActionObserverMap[action]=host;
        router.hostActionSelectorMap[action]=selector;
    }
}


//移除host执行动作
+ (void)removeHostAction:(NSString *)action
{
    if(action)
    {
        KATRouter *router=[self sharedRouter];
        
        [router.hostActionObserverMap deleteValueWithKey:action];
        [router.hostActionSelectorMap deleteValueWithKey:action];
    }
}


//执行host动作(执行时会跳转到该host)
+ (void)doHostAction:(NSString *)action
{
    [self doHostAction:action withObject:nil];
}


//执行带参数的host动作(执行时会跳转到该host)
+ (void)doHostAction:(NSString *)action withObject:(id)obj
{
    if(action)
    {
        KATRouter *router=[self sharedRouter];
        
        NSString *host=router.hostActionObserverMap[action];
        NSString *selector=router.hostActionSelectorMap[action];
        
        if(host && selector)
        {
            if(router.classMap[host])//注册过该host
            {
                //跳转
                [self routeWithURI:host selector:NSSelectorFromString(selector) object:obj addition:nil andHandle:nil];
            }
        }
    }
}


//执行host动作(若forward为NO，且该host没有实例，则不执行)
+ (void)doHostAction:(NSString *)action withObject:(id)obj andForward:(BOOL)forward
{
    if(action)
    {
        KATRouter *router=[self sharedRouter];
        
        NSString *host=router.hostActionObserverMap[action];
        NSString *selector=router.hostActionSelectorMap[action];
        
        if(host && selector)
        {
            if(forward)//跳转
            {
                if(router.classMap[host])//注册过该host
                {
                    //跳转
                    [self routeWithURI:host selector:NSSelectorFromString(selector) object:obj addition:nil andHandle:nil];
                }
            }
            else//不跳转
            {
                if(router.classMap[host] && router.instanceMap[host])//注册过该host，且存在实例
                {
                    if([router.instanceMap[host] respondsToSelector:NSSelectorFromString(selector)])
                    {
                        [router.instanceMap[host] performSelectorOnMainThread:NSSelectorFromString(selector) withObject:obj waitUntilDone:NO];
                    }
                }
            }
        }
    }
}


//清除所有的host动作
+ (void)clearHostActions
{
    KATRouter *router=[self sharedRouter];
    
    [router.hostActionObserverMap clear];
    [router.hostActionSelectorMap clear];
}


#pragma -mark 变量存取

//获取变量(全局)
+ (id)getValueWithKey:(NSString *)key
{
    return [self getValueWithKey:key andHost:kRouterGlobalHost];
}


//通过host获取变量
+ (id)getValueWithKey:(NSString *)key andHost:(NSString *)host
{
    if(!key)
    {
        return nil;
    }
    
    if(!host)//默认为全局
    {
        host=kRouterGlobalHost;
    }
    
    //多例处理
    NSRange range=[host rangeOfString:kRouterMultipleHostMark];
    
    if(range.length>0)
    {
        host=[host substringToIndex:range.location];
    }
    
    KATRouter *router=[self sharedRouter];
    
    KATHashMap *map=router.valueMap[host];
    
    if(map && [map isKindOfClass:[KATHashMap class]])
    {
        return map[key];
    }
    
    return nil;
}


//通过VC实例获取变量
+ (id)getValueWithKey:(NSString *)key andInstance:(UIViewController *)vc
{
    NSString *host=objc_getAssociatedObject(vc, kRouterKeyHost);
    
    return [self getValueWithKey:key andHost:host];
}


//设置变量(全局)
+ (void)setValue:(id)value WithKey:(NSString *)key
{
    [self setValue:value WithKey:key andHost:kRouterGlobalHost];
}


//通过host设置变量
+ (void)setValue:(id)value WithKey:(NSString *)key andHost:(NSString *)host
{
    if(!key)
    {
        return;
    }
    
    if(!host)//默认为全局
    {
        host=kRouterGlobalHost;
    }
    
    //多例处理
    NSRange range=[host rangeOfString:kRouterMultipleHostMark];
    
    if(range.length>0)
    {
        host=[host substringToIndex:range.location];
    }
    
    KATRouter *router=[self sharedRouter];
    
    KATHashMap *map=router.valueMap[host];
    
    if(map && [map isKindOfClass:[KATHashMap class]])
    {
        map[key]=value;
    }
}


//通过VC实例设置变量
+ (void)setValue:(id)value WithKey:(NSString *)key andInstance:(UIViewController *)vc
{
    NSString *host=objc_getAssociatedObject(vc, kRouterKeyHost);
    
    [self setValue:value WithKey:key andHost:host];
}


#pragma -mark 参数配置


//设置首次路由URI(只设置一次)
+ (void)setFirstRouteURI:(NSString *)URI
{
    KATRouter *router=[self sharedRouter];
    
    if(!router.config[kRouterConfigKeyFirstRouteURI])//不存在则设置
    {
        [self changeFirstRouteURI:URI];
    }
}


//更改首次路由URI
+ (void)changeFirstRouteURI:(NSString *)URI
{
    KATRouter *router=[self sharedRouter];
    
    router.config[kRouterConfigKeyFirstRouteURI]=URI;
    
    [router saveConfig];
}


//获取首次路由URI
+ (NSString *)firstRouteURI
{
    KATRouter *router=[self sharedRouter];
    
    return router.config[kRouterConfigKeyFirstRouteURI];
}


//设置转场动画风格的key(方便传参数)
+ (void)setTransitionStyleKey:(NSString *)key
{
    KATRouter *router=[self sharedRouter];
    
    if(!router.config[kRouterConfigKeyTransitionStyleKey])//不存在则设置
    {
        [self changeTransitionStyleKey:key];
    }
}


//更改转场动画风格的key(方便传参数)
+ (void)changeTransitionStyleKey:(NSString *)key
{
    if(!key)
    {
        return;
    }
    
    KATRouter *router=[self sharedRouter];
    
    router.transitionStyleKey=key;
    
    //保存到配置文件
    router.config[kRouterConfigKeyTransitionStyleKey]=router.transitionStyleKey;
    
    [router saveConfig];
    
    //导航栏返回按钮
    if(router.navBar)
    {
        router.navBar.backButton.onClickAction=^
        {
            [KATRouter backwardWithQuery:[NSString stringWithFormat:@"%@=%lu",_router.transitionStyleKey,(unsigned long)KATRouterTransitionStyleNavHorizontal]];
        };
    }
}


//获取转场动画风格的key
+ (NSString *)transitionStyleKey
{
    KATRouter *router=[self sharedRouter];
    
    return router.transitionStyleKey;
}


//设置转场动画风格
+ (void)setTransitionStyle:(KATRouterTransitionStyle)style
{
    KATRouter *router=[self sharedRouter];
    
    if(!router.config[kRouterConfigKeyTransitionStyle])//不存在则设置
    {
        [self changeTransitionStyle:style];
    }
}


//设置转场动画风格
+ (void)changeTransitionStyle:(KATRouterTransitionStyle)style
{
    KATRouter *router=[self sharedRouter];
    
    router.transitionStyle=style;
    
    //保存到配置文件
    router.config[kRouterConfigKeyTransitionStyle]=[NSString stringWithFormat:@"%lu",(unsigned long)router.transitionStyle];
    
    [router saveConfig];
}


//设置转场动画时长的key(方便传参数)(只设置一次)
+ (void)setTransitionDurationKey:(NSString *)key
{
    KATRouter *router=[self sharedRouter];
    
    if(!router.config[kRouterConfigKeyTransitionDurationKey])//不存在则设置
    {
        [self changeTransitionDurationKey:key];
    }
}


//设置host的默认转场动画
+ (void)setTransitionStyle:(KATRouterTransitionStyle)style forHost:(NSString *)host
{
    KATRouter *router=[self sharedRouter];
    
    if(host && router.classMap[host])//注册过
    {
        router.transitionHosts[host]=[NSString stringWithFormat:@"%lu",(unsigned long)style];
    }
}


//设置host数组的默认转场动画
+ (void)setTransitionStyle:(KATRouterTransitionStyle)style forHosts:(KATArray<NSString *> *)hosts
{
    for(NSString *host in hosts)
    {
        [self setTransitionStyle:style forHost:host];
    }
}


//删除host的默认转场动画
+ (void)removeTransitionStyleFromHost:(NSString *)host
{
    KATRouter *router=[self sharedRouter];
    
    if(host)
    {
        router.transitionHosts[host]=nil;
    }
}


//清除所有的host默认转场动画
+ (void)clearTransitionStyleFromAllHosts
{
    KATRouter *router=[self sharedRouter];
    
    [router.transitionHosts clear];
}


//更改转场动画时长的key(方便传参数)
+ (void)changeTransitionDurationKey:(NSString *)key
{
    if(!key)
    {
        return;
    }
    
    KATRouter *router=[self sharedRouter];
    
    router.transitionDurationKey=key;
    
    //保存到配置文件
    router.config[kRouterConfigKeyTransitionDurationKey]=router.transitionDurationKey;
    
    [router saveConfig];
}


//获取转场动画时长的key
+ (NSString *)transitionDurationKey
{
    KATRouter *router=[self sharedRouter];
    
    return router.transitionDurationKey;
}


//设置转场动画时长
+ (void)setTransitionDuration:(double)duration
{
    KATRouter *router=[self sharedRouter];
    
    if(!router.config[kRouterConfigKeyTransitionDuration])//不存在则设置
    {
        [self changeTransitionDuration:duration];
    }
}


//更改转场动画时长
+ (void)changeTransitionDuration:(double)duration
{
    KATRouter *router=[self sharedRouter];
    
    if(duration<0)
    {
        duration=0;
    }
    
    if(duration>ROUTER_TRANSITION_DURATION_MAX)
    {
        duration=ROUTER_TRANSITION_DURATION_MAX;
    }
    
    router.transitionDuration=duration;
    
    //保存到配置文件
    router.config[kRouterConfigKeyTransitionDuration]=[NSString stringWithFormat:@"%lf",router.transitionDuration];
    
    [router saveConfig];
}


//设置路由时是否新建实例的key(方便传参数)(只设置一次)
+ (void)setRoutingWithNewInstanceKey:(NSString *)key
{
    KATRouter *router=[self sharedRouter];
    
    if(!router.config[kRouterConfigKeyRoutingWithNewInstanceKey])//不存在则设置
    {
        [self changeRoutingWithNewInstanceKey:key];
    }
}


//更改路由时是否新建实例的key(方便传参数)
+ (void)changeRoutingWithNewInstanceKey:(NSString *)key
{
    if(!key)
    {
        return;
    }
    
    KATRouter *router=[self sharedRouter];
    
    router.routingWithNewInstanceKey=key;
    
    //保存到配置文件
    router.config[kRouterConfigKeyRoutingWithNewInstanceKey]=router.routingWithNewInstanceKey;
    
    [router saveConfig];
}


//获取路由时是否新建实例的key
+ (NSString *)routingWithNewInstanceKey
{
    KATRouter *router=[self sharedRouter];
    
    return router.routingWithNewInstanceKey;
}


//设置路由时是否创建多例的key(方便传参数)(只设置一次)
+ (void)setRoutingWithMultipleInstanceKey:(NSString *)key
{
    KATRouter *router=[self sharedRouter];
    
    if(!router.config[kRouterConfigKeyRoutingWithMultipleInstanceKey])//不存在则设置
    {
        [self changeRoutingWithMultipleInstanceKey:key];
    }
}


//更改路由时是否创建多例的key(方便传参数)
+ (void)changeRoutingWithMultipleInstanceKey:(NSString *)key
{
    if(!key)
    {
        return;
    }
    
    KATRouter *router=[self sharedRouter];
    
    router.routingWithMultipleInstanceKey=key;
    
    //保存到配置文件
    router.config[kRouterConfigKeyRoutingWithMultipleInstanceKey]=router.routingWithMultipleInstanceKey;
    
    [router saveConfig];
}


//获取路由时是否创建多例的key
+ (NSString *)routingWithMultipleInstanceKey
{
    KATRouter *router=[self sharedRouter];
    
    return router.routingWithMultipleInstanceKey;
}


//设置根视图内容图片
+ (void)setRootContents:(UIImage *)contents
{
    KATRouter *router=[self sharedRouter];
    
    router.rootVC.view.layer.contents=(id)contents.CGImage;
}


//设置定时器间隔
+ (void)setTimerInterval:(double)interval
{
    if(interval<=0)
    {
        interval=ROUTER_MISSION_TIMER_INTERVAL;
    }
    
    KATRouter *router=[self sharedRouter];
    
    router.timerInterval=interval;
    
    //重启定时器
    [router stopDurationMissionTimer];
    [router startDurationMissionTimer];
}


//设置路由最大等待时间(默认为转场动画最大时长)
+ (void)setRoutingWaitDuration:(double)duration
{
    KATRouter *router=[self sharedRouter];
    
    router.routingWaitDuration=duration;
}


//获取根视图控制器
+ (UIViewController *)rootViewController
{
    KATRouter *router=[self sharedRouter];
    
    return router.rootVC;
}


//获取栈顶host
+ (NSString *)topHost
{
    KATRouter *router=[self sharedRouter];
    
    return objc_getAssociatedObject(router.topVC, kRouterKeyHost);
}


//获取栈顶VC(路由器中的栈顶，不一定是app中的栈顶)
+ (UIViewController *)topViewController
{
    KATRouter *router=[self sharedRouter];
    
    return router.topVC;
}


//获取主窗口
+ (UIWindow *)keyWindow
{
    KATRouter *router=[self sharedRouter];
    
    return router.window;
}



#pragma -mark 弹窗

//获取提示窗口(用于设置样式等)
+ (KATAlertWindow *)getAlertWindow
{
    KATRouter *router=[self sharedRouter];
    
    if(!router.alertWindow)
    {
        router.alertWindow=[KATAlertWindow windowWithTitle:nil];
    }
    
    return router.alertWindow;
}


//显示提示窗口(直接显示之前设置过的窗口)
+ (void)showAlertWindow
{
    KATAlertWindow *alertWindow=[self getAlertWindow];
    
    [alertWindow show];
}


//隐藏提示窗口
+ (void)hideAlertWindow
{
    KATAlertWindow *alertWindow=[self getAlertWindow];
    
    [alertWindow hide];
}


//显示提示窗口(设置标题和信息)
+ (void)showAlertWindowWithTitle:(NSString *)title andInfo:(NSString *)info
{
    KATAlertWindow *alertWindow=[self getAlertWindow];
    
    alertWindow.title=title;
    alertWindow.info=info;
    
    [alertWindow show];
}


//获取按钮窗口(用于设置样式等)
+ (KATButtonWindow *)getButtonWindow
{
    KATRouter *router=[self sharedRouter];
    
    if(!router.buttonWindow)
    {
        router.buttonWindow=[KATButtonWindow windowWithTitle:nil];
    }
    
    return router.buttonWindow;
}


//显示按钮窗口(直接显示之前设置过的窗口)
+ (void)showButtonWindow
{
    KATButtonWindow *buttonWindow=[self getButtonWindow];
    
    [buttonWindow show];
}


//隐藏按钮窗口
+ (void)hideButtonWindow
{
    KATButtonWindow *buttonWindow=[self getButtonWindow];
    
    [buttonWindow hide];
}


//显示按钮窗口(设置标题、信息和确认按钮动作，默认带一个取消按钮和一个确认按钮)
+ (void)showButtonWindowWithTitle:(NSString *)title info:(NSString *)info andOnConfirmAction:(void (^)(void))action
{
    __block KATButtonWindow *buttonWindow=[self getButtonWindow];
    
    buttonWindow.title=title;
    buttonWindow.info=info;
    buttonWindow.buttons=ARRAY([KATButton buttonWithFrame:CGRectZero type:KATButtonTypeClose color:KCOLOR_RED lineWidth:1.5 scale:1.0 andOnClickAction:^
    {
        [buttonWindow hide];
    }],
    [KATButton buttonWithFrame:CGRectZero type:KATButtonTypeOK color:KCOLOR_BLUE lineWidth:1.5 scale:1.0 andOnClickAction:^
    {
        if(action)
        {
            action();
        }
        
        [buttonWindow hide];
    }]);
    
    [buttonWindow show];
}


//显示按钮窗口(设置标题、信息和按钮)
+ (void)showButtonWindowWithTitle:(NSString *)title info:(NSString *)info andButtons:(KATArray<KATButton *> *)buttons
{
    KATButtonWindow *buttonWindow=[self getButtonWindow];
    
    buttonWindow.title=title;
    buttonWindow.info=info;
    buttonWindow.buttons=buttons;
    
    [buttonWindow show];
}


//获取选择窗口(用于设置样式等)
+ (KATChoiceWindow *)getChoiceWindow
{
    KATRouter *router=[self sharedRouter];
    
    if(!router.choiceWindow)
    {
        router.choiceWindow=[KATChoiceWindow windowWithTitle:nil];
    }
    
    return router.choiceWindow;
}


//显示选择窗口(直接显示之前设置过的窗口)
+ (void)showChoiceWindow
{
    KATChoiceWindow *choiceWindow=[self getChoiceWindow];
    
    [choiceWindow show];
}


//隐藏选择窗口
+ (void)hideChoiceWindow
{
    KATChoiceWindow *choiceWindow=[self getChoiceWindow];
    
    [choiceWindow hide];
}


//显示选择窗口(设置标题、信息和左右按钮标签及动作)
+ (void)showChoiceWindowWithTitle:(NSString *)title info:(NSString *)info leftButtonLabel:(NSString *)leftLabel leftButtonAction:(void (^)(void))leftAction rightButtonLabel:(NSString *)rightLabel rightButtonAction:(void (^)(void))rightAction
{
    __block KATChoiceWindow *choiceWindow=[self getChoiceWindow];
    
    choiceWindow.title=title;
    choiceWindow.info=info;
    choiceWindow.buttons=ARRAY([KATLabelButton buttonWithFrame:CGRectZero text:leftLabel font:nil color:KCOLOR_BLUE andAction:^
    {
        if(leftAction)
        {
            leftAction();
        }
        
        [choiceWindow hide];
    }],
    [KATLabelButton buttonWithFrame:CGRectZero text:rightLabel font:nil color:KCOLOR_BLUE andAction:^
    {
        if(rightAction)
        {
            rightAction();
        }
        
        [choiceWindow hide];
    }]);
    
    [choiceWindow show];
}


//显示选择窗口(设置标题、信息和按钮)
+ (void)showChoiceWindowWithTitle:(NSString *)title info:(NSString *)info andButtons:(KATArray<KATLabelButton *> *)buttons
{
    KATChoiceWindow *choiceWindow=[self getChoiceWindow];
    
    choiceWindow.title=title;
    choiceWindow.info=info;
    choiceWindow.buttons=buttons;
    
    [choiceWindow show];
}


//获取输入窗口(用于设置样式等)
+ (KATInputWindow *)getInputWindow
{
    KATRouter *router=[self sharedRouter];
    
    if(!router.inputWindow)
    {
        router.inputWindow=[KATInputWindow windowWithTitle:nil];
    }
    
    return router.inputWindow;
}


//显示输入窗口(直接显示之前设置过的窗口)
+ (void)showInputWindow
{
    KATInputWindow *inputWindow=[self getInputWindow];
    
    [inputWindow show];
}


//隐藏输入窗口
+ (void)hideInputWindow
{
    KATInputWindow *inputWindow=[self getInputWindow];
    
    [inputWindow hide];
}


//显示输入窗口(设置标题和确认动作)
+ (void)showInputWindowWithTitle:(NSString *)title andOnConfirmAction:(void (^)(NSString *text))action
{
    KATInputWindow *inputWindow=[self getInputWindow];
    
    inputWindow.title=title;
    inputWindow.onConfirmAction=action;
    
    [inputWindow show];
}


//获取输入框窗口(用于设置样式等)
+ (KATTextFieldWindow *)getTextFieldWindow
{
    KATRouter *router=[self sharedRouter];
    
    if(!router.textFieldWindow)
    {
        router.textFieldWindow=[KATTextFieldWindow windowWithTitle:nil style:nil leftButtonLabel:nil leftButtonAction:nil rightButtonLabel:nil rightButtonAction:nil];
    }
    
    return router.textFieldWindow;
}


//显示输入框窗口(直接显示之前设置过的窗口)
+ (void)showTextFieldWindow
{
    KATTextFieldWindow *textFieldWindow=[self getTextFieldWindow];
    
    [textFieldWindow show];
}


//隐藏输入框窗口
+ (void)hideTextFieldWindow
{
    KATTextFieldWindow *textFieldWindow=[self getTextFieldWindow];
    
    [textFieldWindow hide];
}


//显示输入框窗口(设置标题、信息和左右按钮标签及动作)
+ (void)showTextFieldWindowWithTitle:(NSString *)title leftButtonLabel:(NSString *)leftLabel leftButtonAction:(void (^)(NSString *text))leftAction rightButtonLabel:(NSString *)rightLabel rightButtonAction:(void (^)(NSString *text))rightAction
{
    KATTextFieldWindow *textFieldWindow=[self getTextFieldWindow];
    
    textFieldWindow.title=title;
    textFieldWindow.leftButton.label.text=leftLabel;
    textFieldWindow.leftAction=leftAction;
    textFieldWindow.rightButton.label.text=rightLabel;
    textFieldWindow.rightAction=rightAction;
    
    [textFieldWindow show];
}


//获取等待窗口(用于设置样式等)
+ (KATWaitWindow *)getWaitWindow
{
    KATRouter *router=[self sharedRouter];
    
    if(!router.waitWindow)
    {
        router.waitWindow=[KATWaitWindow waitingWithStyle:KATWaitWindowStyleLight];
    }
    
    return router.waitWindow;
}


//显示等待窗口(直接显示之前设置过的窗口)
+ (void)showWaitWindow
{
    KATWaitWindow *waitWindow=[self getWaitWindow];
    
    [waitWindow show];
}


//隐藏等待窗口
+ (void)hideWaitWindow
{
    KATWaitWindow *waitWindow=[self getWaitWindow];
    
    [waitWindow hide];
}


//获取加载窗口(用于设置样式等)
+ (KATWaitWindow *)getLoadingWindow
{
    KATRouter *router=[self sharedRouter];
    
    if(!router.loadingWindow)
    {
        router.loadingWindow=[KATWaitWindow loadingWithStyle:KATWaitWindowStyleLight];
    }
    
    return router.loadingWindow;
}


//显示加载窗口(直接显示之前设置过的窗口)
+ (void)showLoadingWindow
{
    KATWaitWindow *loadingWindow=[self getLoadingWindow];
    
    [loadingWindow show];
}


//隐藏加载窗口
+ (void)hideLoadingWindow
{
    KATWaitWindow *loadingWindow=[self getLoadingWindow];
    
    [loadingWindow hide];
}


//加载成功
+ (void)loadingWindowSuccessWithMessage:(NSString *)message
{
    KATWaitWindow *loadingWindow=[self getLoadingWindow];
    
    [loadingWindow finishWithValue:KATAnimationFinishValueSuccess andMessage:message];
}


//加载失败
+ (void)loadingWindowFailWithMessage:(NSString *)message
{
    KATWaitWindow *loadingWindow=[self getLoadingWindow];
    
    [loadingWindow finishWithValue:KATAnimationFinishValueFail andMessage:message];
}


//获取吐司(用于设置样式等)
+ (KATToast *)getToast
{
    KATRouter *router=[self sharedRouter];
    
    if(!router.toast)
    {
        router.toast=[KATToast toast];
    }
    
    return router.toast;
}


//显示吐司(直接显示之前设置过的窗口)
+ (void)showToast
{
    KATToast *toast=[self getToast];
    
    [toast show];
}


//显示吐司(设置文本)
+ (void)showToastWithText:(NSString *)text
{
    KATToast *toast=[self getToast];
    
    toast.buttonType=KATButtonTypeNone;
    toast.text=text;
    
    [toast show];
}


//显示吐司(设置按钮)
+ (void)showToastWithButton:(KATButtonType)button
{
    KATToast *toast=[self getToast];
    
    toast.buttonType=button;
    toast.text=nil;
    
    [toast show];
}


//显示吐司(设置文本、按钮、时长和位置)
+ (void)showToastWithText:(NSString *)text button:(KATButtonType)button duration:(float)duration andPosition:(int)position
{
    KATToast *toast=[self getToast];
    
    toast.buttonType=button;
    toast.text=text;
    toast.duration=duration;
    toast.position=position;
    
    [toast show];
}



#pragma -mark 内容管理


//判断路由器是否正在跳转中
+ (BOOL)isRouting
{
    KATRouter *router=[self sharedRouter];
    
    return router.isRouting;
}


//通过类获取host
+ (NSString *)hostWithClass:(Class)cls
{
    return [self hostWithClassName:NSStringFromClass(cls)];
}


//通过类名获取host
+ (NSString *)hostWithClassName:(NSString *)name
{
    if(name)
    {
        KATRouter *router=[self sharedRouter];
        
        return [router.classMap getKeyWithValue:name];
    }
    
    return nil;
}


//通过实例获取host
+ (NSString *)hostWithInstance:(UIViewController *)instance
{
    if(instance)
    {
        KATRouter *router=[self sharedRouter];
        
        return [router.instanceMap getKeyWithValue:instance];
    }
    
    return nil;
}


//获取当前的host
+ (NSString *)currentHost
{
    KATRouter *router=[self sharedRouter];
    
    NSString *host=[router.instanceMap getKeyWithValue:[KATAppUtil topViewController]];
    
    //多例处理
    NSRange range=[host rangeOfString:kRouterMultipleHostMark];
    
    if(range.length>0)
    {
        host=[host substringToIndex:range.location];
    }
    
    return host;
}


//正在路由的host
+ (NSString *)routingHost
{
    KATRouter *router=[self sharedRouter];
    
    return router.showingHost;
}


//获取当前的host的实例
+ (UIViewController *)currentHostInstance
{
    return [KATAppUtil topViewController];
}


//判断是否为当前的host
+ (BOOL)isCurrentHost:(NSString *)host
{
    if(host)
    {
        return [host isEqualToString:[self currentHost]];
    }
    
    return NO;
}


//判断是否为当前的host实例
+ (BOOL)isCurrentHostInstance:(UIViewController *)instance
{
    if(instance)
    {
        return (instance==[self currentHostInstance]);
    }
    
    return NO;
}


//获取类
+ (Class)classWithHost:(NSString *)host
{
    if(host)
    {
        KATRouter *router=[self sharedRouter];
        
        return NSClassFromString(router.classMap[host]);
    }
    
    return nil;
}


//获取实例
+ (UIViewController *)instanceWithHost:(NSString *)host
{
    if(host)
    {
        KATRouter *router=[self sharedRouter];
        
        return router.instanceMap[host];
    }
    
    return nil;
}


//释放实例
+ (void)releaseInstance:(UIViewController *)instance
{
    if(instance)
    {
        NSString *host=objc_getAssociatedObject(instance, kRouterKeyHost);
        
        [self releaseInstanceWithHost:host];
    }
}


//释放实例
+ (void)releaseInstanceWithHost:(NSString *)host
{
    if(!host)
    {
        return;
    }
    
    if([host isEqualToString:kRouterRootHost])
    {
        return;
    }
    
    KATRouter *router=[self sharedRouter];
    
    if(router.instanceMap[host])
    {
        //回调方法
        if([router.instanceMap[host] conformsToProtocol:@protocol(KATRouterDelegate)] && [router.instanceMap[host] respondsToSelector:@selector(instanceWillBeReleased)])
        {
            [(id<KATRouterDelegate>)router.instanceMap[host] instanceWillBeReleased];
        }
        
        //取消关联
        objc_removeAssociatedObjects(router.instanceMap[host]);
        
        if([NSThread currentThread]==[NSThread mainThread])
        {
            //删除滑动手势
            [self removeSlideHost:host];
        }
        else
        {
            GCD_SYNC_MAIN(
            {
                //删除滑动手势
                [self removeSlideHost:host];
            });
        }
        
        NSRange range=[host rangeOfString:kRouterMultipleHostMark];
        
        if(range.length>0)//多例对象
        {
            //删除类表
            [router.classMap deleteValueWithKey:host];
            
            //删除值表
            [router.valueMap deleteValueWithKey:host];
            
            //移除消息表
            [KATRouter removeObserverForAllMessageTypesWithHost:host];
        }
        
        //顶层判断
        if(router.instanceMap[host]==router.topVC)
        {
            router.topVC=router.rootVC;
        }
        
        [router.instanceMap deleteValueWithKey:host];
    }
}


//释放所有实例
+ (void)releaseAllInstances
{
    KATRouter *router=[self sharedRouter];
    
    //取消关联
    KATArray *hosts=[router.instanceMap allValues];
    
    for(int i=0;i<hosts.length;i++)
    {
        objc_removeAssociatedObjects(hosts[i]);
    }
    
    [router.instanceMap clear];
}


//释放单例
+ (void)releaseRouter
{
    [_router release];
    
    _router=nil;
}


//添加一直持有的host
+ (void)addAlwaysRetainedHost:(NSString *)host
{
    if(host)
    {
        KATRouter *router=[self sharedRouter];
        
        [router.alwaysRetainedHosts putWithKey:host andValue:host];
    }
}


//添加一直持有的host数组
+ (void)addAlwaysRetainedHosts:(KATArray<NSString *> *)hosts
{
    if(hosts && hosts.length>0)
    {
        KATRouter *router=[self sharedRouter];
        
        for(NSString *host in hosts)
        {
            [router.alwaysRetainedHosts putWithKey:host andValue:host];
        }
    }
}


//删除一直持有的host
+ (void)removeAlwaysRetainedHost:(NSString *)host
{
    if(host)
    {
        KATRouter *router=[self sharedRouter];
        
        router.alwaysRetainedHosts[host]=nil;
    }
}


//添加路由时新建实例的host
+ (void)addRoutingWithNewInstanceHost:(NSString *)host
{
    if(host)
    {
        KATRouter *router=[self sharedRouter];
        
        [router.routingWithNewInstanceHosts putWithKey:host andValue:host];
    }
}


//添加路由时新建实例的host数组
+ (void)addRoutingWithNewInstanceHosts:(KATArray<NSString *> *)hosts
{
    if(hosts && hosts.length>0)
    {
        KATRouter *router=[self sharedRouter];
        
        for(NSString *host in hosts)
        {
            [router.routingWithNewInstanceHosts putWithKey:host andValue:host];
        }
    }
}


//删除路由时新建实例的host
+ (void)removeRoutingWithNewInstanceHost:(NSString *)host
{
    if(host)
    {
        KATRouter *router=[self sharedRouter];
        
        router.routingWithNewInstanceHosts[host]=nil;
    }
}


//添加路由时创建多例的host
+ (void)addRoutingWithMultipleInstanceHost:(NSString *)host
{
    if(host)
    {
        KATRouter *router=[self sharedRouter];
        
        [router.routingWithMultipleInstanceHosts putWithKey:host andValue:host];
    }
}


//添加路由时创建多例的host数组
+ (void)addRoutingWithMultipleInstanceHosts:(KATArray<NSString *> *)hosts
{
    if(hosts && hosts.length>0)
    {
        KATRouter *router=[self sharedRouter];
        
        for(NSString *host in hosts)
        {
            [router.routingWithMultipleInstanceHosts putWithKey:host andValue:host];
        }
    }
}


//删除路由时创建多例的host
+ (void)removeRoutingWithMultipleInstanceHost:(NSString *)host
{
    if(host)
    {
        KATRouter *router=[self sharedRouter];
        
        router.routingWithMultipleInstanceHosts[host]=nil;
    }
}


//添加需要接收截图的host
+ (void)addRequeredSnapshotHost:(NSString *)host
{
    if(host)
    {
        KATRouter *router=[self sharedRouter];
        
        [router.requiredSnapshotHosts putWithKey:host andValue:host];
    }
}


//添加需要接收截图的host数组
+ (void)addRequeredSnapshotHosts:(KATArray<NSString *> *)hosts
{
    if(hosts && hosts.length>0)
    {
        KATRouter *router=[self sharedRouter];
        
        for(NSString *host in hosts)
        {
            [router.requiredSnapshotHosts putWithKey:host andValue:host];
        }
    }
}


//删除需要接收截图的host
+ (void)removeRequeredSnapshotHost:(NSString *)host
{
    if(host)
    {
        KATRouter *router=[self sharedRouter];
        
        router.requiredSnapshotHosts[host]=nil;
    }
}


//获取返回栈
+ (KATStack<NSString *> *)backwardStack
{
    KATRouter *router=[self sharedRouter];
    
    return [router.backwardStack copy];
}


//将host插入到返回栈上的目标host之下
+ (BOOL)insertHost:(NSString *)host toBackwardStack:(NSString *)targetHost
{
    KATRouter *router=[self sharedRouter];
    
    return [router.backwardStack insert:host toMember:targetHost];
}


//将host插入到返回栈上的目标host之上
+ (BOOL)appendHost:(NSString *)host toBackwardStack:(NSString *)targetHost
{
    KATRouter *router=[self sharedRouter];
    
    return [router.backwardStack append:host toMember:targetHost];
}


//将host插入到返回栈上的栈顶
+ (BOOL)appendToBackwardStackWithHost:(NSString *)host
{
    KATRouter *router=[self sharedRouter];
    
    return [router.backwardStack put:host];
}


//将返回栈上的host删除
+ (void)removeHostFromBackwardStack:(NSString *)host
{
    KATRouter *router=[self sharedRouter];
    
    [router.backwardStack deleteMember:host];
}



//释放内存
- (void)dealloc
{
    //清除动作
    [KATRouter clearActions];
    [KATRouter clearHostActions];
    
    //清除消息监听器
    [KATRouter clearMessageObservers];
    
    //清除实例
    [KATRouter releaseAllInstances];
    
    //停止定时器
    [self stopDurationMissionTimer];
    
    //取消通知
    [[NSNotificationCenter defaultCenter] removeObserver:self];
    
    [_app release];
    [_window release];
    [_rootVC release];
    [_topVC release];
    [_classMap release];
    [_instanceMap release];
    [_backwardStack release];
    [_valueMap release];
    [_messageTypeMap release];
    [_actionObserverMap release];
    [_actionSelectorMap release];
    [_hostActionObserverMap release];
    [_hostActionSelectorMap release];
    [_transitionStyleKey release];
    [_transitionDurationKey release];
    [_routingWithNewInstanceKey release];
    [_routingWithMultipleInstanceKey release];
    [_navTransition release];
    [_tabBar release];
    [_navBar release];
    [_showingHost release];
    [_lastURI release];
    
    [_portraitOrientationHosts release];
    [_landscapeOrientationHosts release];
    [_freeOrientationHosts release];
    [_transitionHosts release];
    
    [_historyLogs release];
    [_dayLogs release];
    [_appLog release];
    [_hostLog release];
    [_logsDir release];
    [_logsUploadURL release];
    [_logsID release];
    [_logsUploadContentKey release];
    [_logsUploadExtra release];
    
    [_daysMissions release];
    [_durationMissions release];
    [_countMissions release];
    
    [_alwaysRetainedHosts release];
    [_routingWithNewInstanceHosts release];
    [_routingWithMultipleInstanceHosts release];
    [_requiredSnapshotHosts release];
    
    [_slideHosts release];
    [_slideDisabledHosts release];
    [_slideBackgroundViews release];
    [_slideForegroundView release];
    [_slideBackgroundView release];
    [_slideEmptyView release];
    [_slideShadowView release];
    [_slideGestures release];
    
    [_profile release];
    [_config release];
    
    [_alertWindow release];
    [_buttonWindow release];
    [_choiceWindow release];
    [_inputWindow release];
    [_textFieldWindow release];
    [_waitWindow release];
    [_loadingWindow release];
    [_toast release];
    
    dispatch_release(_queueRouting);
    dispatch_release(_queueLogsSaving);
    dispatch_release(_queueLogsUploading);
    dispatch_release(_queueDurationMissions);
    
    [_durationMissionsTimer release];
    
    Block_release(_logsDidUploadAction);
    Block_release(_appDidBecomeActiveAction);
    Block_release(_appWillResignActiveAction);
    Block_release(_appWillEnterForegroundAction);
    Block_release(_appDidEnterBackgroundAction);
    Block_release(_appWillTerminateAction);
    Block_release(_appOpenedWithURLAction);
    Block_release(_appReceivedNotificationAction);
    Block_release(_appRegisteredNotificationAction);
    
    Block_release(_routeWithURIAction);
    Block_release(_routeAction);
    Block_release(_timerAction);
    
    [super dealloc];
}


@end





@implementation KATRouterRootVC


- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
    if(!_router)
    {
        return UIInterfaceOrientationMaskAll;
    }
    
    if(_router.showingHost)
    {
        //先判断是否为自由方向
        if([_router.freeOrientationHosts getValueWithKey:_router.showingHost])
        {
            return UIInterfaceOrientationMaskAll;
        }
        
        if(_router.isLandscapeOrientationDefault)//默认横屏
        {
            if([_router.portraitOrientationHosts getValueWithKey:_router.showingHost])
            {
                return (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown);
            }
            else
            {
                return (UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight);
            }
        }
        else//默认竖屏
        {
            if([_router.landscapeOrientationHosts getValueWithKey:_router.showingHost])
            {
                return (UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight);
            }
            else
            {
                return (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown);
            }
        }
    }
    
    return UIInterfaceOrientationMaskAll;
}

@end





